Assorted Python changes based on a code review.
Many changes were based on conventions in the Python socketmodule. Changed many of the docstrings to match the Python socket library conventions and enhancing them. I can either remove the prototype part or add it to other docstrings in the library, depending on feedback I get. Changed setblocking to use the flag argument instead of always just setting NONBLOCK. Added enable/disable threading around more lwip calls. Implementing optional backlog on listen(). Removing a few seemingly unneeded Py_INCREF(Py_None) calls. Moved getblocking function based on alpha sorting of names.
This commit is contained in:
@@ -26,22 +26,46 @@
|
|||||||
|
|
||||||
#ifdef ZTS_ENABLE_PYTHON
|
#ifdef ZTS_ENABLE_PYTHON
|
||||||
|
|
||||||
int zts_py_setblocking(int fd, int flag)
|
int zts_py_setblocking(int fd, int block)
|
||||||
{
|
{
|
||||||
int flags = ZTS_ERR_OK;
|
int new_flags, flags, err = 0;
|
||||||
if ((flags = zts_fcntl(fd, F_GETFL, 0)) < 0) {
|
|
||||||
return ZTS_ERR_SOCKET;
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
flags = zts_fcntl(fd, F_GETFL, 0);
|
||||||
|
|
||||||
|
if (flags < 0) {
|
||||||
|
err = ZTS_ERR_SOCKET;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
return zts_fcntl(fd, F_SETFL, flags | ZTS_O_NONBLOCK);
|
|
||||||
|
if (block) {
|
||||||
|
new_flags |= ZTS_O_NONBLOCK;
|
||||||
|
} else {
|
||||||
|
new_flags &= ~ZTS_O_NONBLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_flags != flags) {
|
||||||
|
err = zts_fcntl(fd, F_SETFL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_py_getblocking(int fd)
|
int zts_py_getblocking(int fd)
|
||||||
{
|
{
|
||||||
int flags = ZTS_ERR_OK;
|
int flags;
|
||||||
if ((flags = zts_fcntl(fd, F_GETFL, 0)) < 0) {
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
flags = zts_fcntl(fd, F_GETFL, 0);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
if (flags < 0) {
|
||||||
return ZTS_ERR_SOCKET;
|
return ZTS_ERR_SOCKET;
|
||||||
}
|
}
|
||||||
return flags & ZTS_O_NONBLOCK;
|
return flags & ZTS_O_NONBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zts_py_tuple_to_sockaddr(int family,
|
static int zts_py_tuple_to_sockaddr(int family,
|
||||||
@@ -98,6 +122,9 @@ PyObject * zts_py_accept(int fd)
|
|||||||
|
|
||||||
int zts_py_listen(int fd, int backlog)
|
int zts_py_listen(int fd, int backlog)
|
||||||
{
|
{
|
||||||
|
if (backlog < 0) {
|
||||||
|
backlog = 128;
|
||||||
|
}
|
||||||
return zts_listen(fd, backlog);
|
return zts_listen(fd, backlog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +141,6 @@ int zts_py_bind(int fd, int family, int type, PyObject *addr_obj)
|
|||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
err = zts_bind(fd, (struct zts_sockaddr *)&addrbuf, addrlen);
|
err = zts_bind(fd, (struct zts_sockaddr *)&addrbuf, addrlen);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
Py_INCREF(Py_None);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +157,6 @@ int zts_py_connect(int fd, int family, int type, PyObject *addr_obj)
|
|||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
err = zts_connect(fd, (struct zts_sockaddr *)&addrbuf, addrlen);
|
err = zts_connect(fd, (struct zts_sockaddr *)&addrbuf, addrlen);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
Py_INCREF(Py_None);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +232,11 @@ int zts_py_send(int fd, PyObject *buf, int flags)
|
|||||||
|
|
||||||
int zts_py_close(int fd)
|
int zts_py_close(int fd)
|
||||||
{
|
{
|
||||||
return zts_close(fd);
|
int err;
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
err = zts_close(fd);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ZTS_ENABLE_PYTHON
|
#endif // ZTS_ENABLE_PYTHON
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# This file was automatically generated by SWIG (http://www.swig.org).
|
# This file was automatically generated by SWIG (http://www.swig.org).
|
||||||
# Version 4.0.2
|
# Version 4.0.1
|
||||||
#
|
#
|
||||||
# Do not make changes to this file unless you know what you are doing--modify
|
# Do not make changes to this file unless you know what you are doing--modify
|
||||||
# the SWIG interface file instead.
|
# the SWIG interface file instead.
|
||||||
|
|||||||
@@ -236,7 +236,11 @@ class socket:
|
|||||||
raise NotImplementedError("if_indextoname(): libzt does not name interfaces.")
|
raise NotImplementedError("if_indextoname(): libzt does not name interfaces.")
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
"""Accept connection on the socket"""
|
"""accept() -> (socket, address_info)
|
||||||
|
|
||||||
|
Wait for incoming connection and return a tuple of socket object and
|
||||||
|
client address info. This address info may be a tuple of host address
|
||||||
|
and port."""
|
||||||
new_conn_fd, addr, port = libzt.zts_py_accept(self._fd)
|
new_conn_fd, addr, port = libzt.zts_py_accept(self._fd)
|
||||||
if new_conn_fd < 0:
|
if new_conn_fd < 0:
|
||||||
handle_error(new_conn_fd)
|
handle_error(new_conn_fd)
|
||||||
@@ -244,25 +248,33 @@ class socket:
|
|||||||
return socket(self._family, self._type, self._proto, new_conn_fd), addr
|
return socket(self._family, self._type, self._proto, new_conn_fd), addr
|
||||||
|
|
||||||
def bind(self, local_address):
|
def bind(self, local_address):
|
||||||
"""Bind the socket to a local interface address"""
|
"""bind(address)
|
||||||
|
|
||||||
|
Bind the socket to a local interface address"""
|
||||||
err = libzt.zts_py_bind(self._fd, self._family, self._type, local_address)
|
err = libzt.zts_py_bind(self._fd, self._family, self._type, local_address)
|
||||||
if err < 0:
|
if err < 0:
|
||||||
handle_error(err)
|
handle_error(err)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Close the socket"""
|
"""close()
|
||||||
|
|
||||||
|
Close the socket"""
|
||||||
err = libzt.zts_py_close(self._fd)
|
err = libzt.zts_py_close(self._fd)
|
||||||
if err < 0:
|
if err < 0:
|
||||||
handle_error(err)
|
handle_error(err)
|
||||||
|
|
||||||
def connect(self, remote_address):
|
def connect(self, remote_address):
|
||||||
"""Connect the socket to a remote address"""
|
"""connect(address)
|
||||||
|
|
||||||
|
Connect the socket to a remote address"""
|
||||||
err = libzt.zts_py_connect(self._fd, self._family, self._type, remote_address)
|
err = libzt.zts_py_connect(self._fd, self._family, self._type, remote_address)
|
||||||
if err < 0:
|
if err < 0:
|
||||||
handle_error(err)
|
handle_error(err)
|
||||||
|
|
||||||
def connect_ex(self, remote_address):
|
def connect_ex(self, remote_address):
|
||||||
"""Connect to remote host but return low-level result code, and errno on failure
|
"""connect_ex(address) -> errno
|
||||||
|
|
||||||
|
Connect to remote host but return low-level result code, and errno on failure
|
||||||
This uses a non-thread-safe implementation of errno
|
This uses a non-thread-safe implementation of errno
|
||||||
"""
|
"""
|
||||||
err = libzt.zts_py_connect(self._fd, self._family, self._type, remote_address)
|
err = libzt.zts_py_connect(self._fd, self._family, self._type, remote_address)
|
||||||
@@ -287,6 +299,12 @@ class socket:
|
|||||||
"""libzt does not support this (yet)"""
|
"""libzt does not support this (yet)"""
|
||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
|
def getblocking(self):
|
||||||
|
"""getblocking()
|
||||||
|
|
||||||
|
Return True if the socket is in blocking mode, False if it is non-blocking"""
|
||||||
|
return libzt.zts_py_getblocking(self._fd)
|
||||||
|
|
||||||
def getpeername(self):
|
def getpeername(self):
|
||||||
"""libzt does not support this (yet)"""
|
"""libzt does not support this (yet)"""
|
||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
@@ -299,10 +317,6 @@ class socket:
|
|||||||
"""libzt does not support this (yet)"""
|
"""libzt does not support this (yet)"""
|
||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
def getblocking(self):
|
|
||||||
"""Get whether this socket is in blocking or non-blocking mode"""
|
|
||||||
return libzt.zts_py_getblocking(self._fd)
|
|
||||||
|
|
||||||
def gettimeout(self):
|
def gettimeout(self):
|
||||||
"""libzt does not support this (yet)"""
|
"""libzt does not support this (yet)"""
|
||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
@@ -311,8 +325,19 @@ class socket:
|
|||||||
"""libzt does not support this (yet)"""
|
"""libzt does not support this (yet)"""
|
||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
def listen(self, backlog):
|
def listen(self, backlog=None):
|
||||||
"""Put the socket in a listening state (with an optional backlog argument)"""
|
"""listen([backlog])
|
||||||
|
|
||||||
|
Put the socket in a listening state. Backlog specifies the number of
|
||||||
|
outstanding connections the OS will queue without being accepted. If
|
||||||
|
less than 0, it is set to 0. If not specified, a reasonable default
|
||||||
|
will be used."""
|
||||||
|
|
||||||
|
if backlog is not None and backlog < 0:
|
||||||
|
backlog = 0
|
||||||
|
if backlog is None:
|
||||||
|
backlog = -1 # Lower-level code picks default
|
||||||
|
|
||||||
err = libzt.zts_py_listen(self._fd, backlog)
|
err = libzt.zts_py_listen(self._fd, backlog)
|
||||||
if err < 0:
|
if err < 0:
|
||||||
handle_error(err)
|
handle_error(err)
|
||||||
@@ -322,7 +347,16 @@ class socket:
|
|||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
def recv(self, n_bytes, flags=0):
|
def recv(self, n_bytes, flags=0):
|
||||||
"""Read data from the socket"""
|
"""recv(buffersize[, flags]) -> data
|
||||||
|
|
||||||
|
Read up to buffersize bytes from remote. Wait until at least one byte
|
||||||
|
is read, or remote is closed. If all data is read and remote is closed,
|
||||||
|
returns empty string. Flags may be:
|
||||||
|
|
||||||
|
- ZTS_MSG_PEEK - Peeks at an incoming message.
|
||||||
|
- ZTS_MSG_DONTWAIT - Nonblocking I/O for this operation only.
|
||||||
|
- ZTS_MSG_MORE - Wait for more than one message.
|
||||||
|
"""
|
||||||
err, data = libzt.zts_py_recv(self._fd, n_bytes, flags)
|
err, data = libzt.zts_py_recv(self._fd, n_bytes, flags)
|
||||||
if err < 0:
|
if err < 0:
|
||||||
handle_error(err)
|
handle_error(err)
|
||||||
@@ -350,7 +384,16 @@ class socket:
|
|||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
def send(self, data, flags=0):
|
def send(self, data, flags=0):
|
||||||
"""Write data to the socket"""
|
"""send(data[, flags]) -> count
|
||||||
|
|
||||||
|
Write data to the socket. Returns the number of bytes sent, which
|
||||||
|
may be less than the full data size if the network is busy.
|
||||||
|
Optional flags may be:
|
||||||
|
|
||||||
|
- ZTS_MSG_PEEK - Peeks at an incoming message.
|
||||||
|
- ZTS_MSG_DONTWAIT - Nonblocking I/O for this operation only.
|
||||||
|
- ZTS_MSG_MORE - Sender will send more.
|
||||||
|
"""
|
||||||
err = libzt.zts_py_send(self._fd, data, flags)
|
err = libzt.zts_py_send(self._fd, data, flags)
|
||||||
if err < 0:
|
if err < 0:
|
||||||
handle_error(err)
|
handle_error(err)
|
||||||
@@ -389,8 +432,10 @@ class socket:
|
|||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
def setblocking(self, flag):
|
def setblocking(self, flag):
|
||||||
"""Set whether this socket is in blocking or non-blocking mode"""
|
"""setblocking(flag)
|
||||||
libzt.zts_py_setblocking(self._fd, flag)
|
|
||||||
|
Sets the socket to blocking mode if flag=True, non-blocking if flag=False."""
|
||||||
|
libzt.zts_py_setblocking(self._fd, block)
|
||||||
|
|
||||||
def settimeout(self, value):
|
def settimeout(self, value):
|
||||||
"""libzt does not support this (yet)"""
|
"""libzt does not support this (yet)"""
|
||||||
@@ -404,5 +449,12 @@ class socket:
|
|||||||
raise NotImplementedError("libzt does not support this (yet?)")
|
raise NotImplementedError("libzt does not support this (yet?)")
|
||||||
|
|
||||||
def shutdown(self, how):
|
def shutdown(self, how):
|
||||||
"""Shut down one or more aspects (rx/tx) of the socket"""
|
"""shutdown(how)
|
||||||
|
|
||||||
|
Shut down one or more aspects (rx/tx) of the socket depending on how:
|
||||||
|
|
||||||
|
- ZTS_SHUT_RD - Shut down reading side of socket.
|
||||||
|
- ZTS_SHUT_WR - Shut down writing side of socket.
|
||||||
|
- ZTS_SHUT_RDWR - Both ends of the socket.
|
||||||
|
"""
|
||||||
libzt.zts_shutdown(self._fd, how)
|
libzt.zts_shutdown(self._fd, how)
|
||||||
|
|||||||
Reference in New Issue
Block a user