aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/socketmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r--Modules/socketmodule.c995
1 files changed, 465 insertions, 530 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 506a2d320b6..4f896fd41ea 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -20,15 +20,14 @@ Module interface:
a subclass of socket.error
- socket.herror: exception raised for gethostby* errors,
a subclass of socket.error
-- socket.fromfd(fd, family, type[, proto]) --> new socket object (created
- from an existing file descriptor)
- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
- socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...])
- socket.gethostname() --> host name (string: 'spam' or 'spam.domain.com')
- socket.getprotobyname(protocolname) --> protocol number
- socket.getservbyname(servicename[, protocolname]) --> port number
- socket.getservbyport(portnumber[, protocolname]) --> service name
-- socket.socket([family[, type [, proto]]]) --> new socket object
+- socket.socket([family[, type [, proto, fileno]]]) --> new socket object
+ (fileno specifies a pre-existing socket file descriptor)
- socket.socketpair([family[, type [, proto]]]) --> (socket, socket)
- socket.ntohs(16 bit value) --> new int object
- socket.ntohl(32 bit value) --> new int object
@@ -110,19 +109,18 @@ A socket object represents one endpoint of a network connection.\n\
\n\
Methods of socket objects (keyword arguments not allowed):\n\
\n\
-accept() -- accept a connection, returning new socket and client address\n\
+_accept() -- accept connection, returning new socket fd and client address\n\
bind(addr) -- bind the socket to a local address\n\
close() -- close the socket\n\
connect(addr) -- connect the socket to a remote address\n\
connect_ex(addr) -- connect, return an error code instead of an exception\n\
-dup() -- return a new socket object identical to the current one [*]\n\
+_dup() -- return a new socket fd duplicated from fileno()\n\
fileno() -- return underlying file descriptor\n\
getpeername() -- return remote address [*]\n\
getsockname() -- return local address\n\
getsockopt(level, optname[, buflen]) -- get socket options\n\
gettimeout() -- return timeout or None\n\
listen(n) -- start listening for incoming connections\n\
-makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
recv(buflen[, flags]) -- receive data\n\
recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
@@ -264,24 +262,14 @@ shutdown(how) -- shut down traffic in one or both directions\n\
# include <netdb.h>
/* Headers needed for inet_ntoa() and inet_addr() */
-# ifdef __BEOS__
-# include <net/netdb.h>
-# elif defined(PYOS_OS2) && defined(PYCC_VACPP)
+# if defined(PYOS_OS2) && defined(PYCC_VACPP)
# include <netdb.h>
typedef size_t socklen_t;
# else
# include <arpa/inet.h>
# endif
-# ifndef RISCOS
# include <fcntl.h>
-# else
-# include <sys/ioctl.h>
-# include <socklib.h>
-# define NO_DUP
-int h_errno; /* not used */
-# define INET_ADDRSTRLEN 16
-# endif
#else
@@ -358,11 +346,23 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#include "getnameinfo.c"
#endif
-#if defined(MS_WINDOWS) || defined(__BEOS__)
-/* BeOS suffers from the same socket dichotomy as Win32... - [cjh] */
-/* seem to be a few differences in the API */
+#ifdef MS_WINDOWS
+/* On Windows a socket is really a handle not an fd */
+static SOCKET
+dup_socket(SOCKET handle)
+{
+ WSAPROTOCOL_INFO info;
+
+ if (WSADuplicateSocket(handle, GetCurrentProcessId(), &info))
+ return INVALID_SOCKET;
+
+ return WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
+ FROM_PROTOCOL_INFO, &info, 0, 0);
+}
#define SOCKETCLOSE closesocket
-#define NO_DUP /* Actually it exists on NT 3.5, but what the heck... */
+#else
+/* On Unix we can use dup to duplicate the file descriptor of a socket*/
+#define dup_socket(fd) dup(fd)
#endif
#ifdef MS_WIN32
@@ -429,6 +429,10 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#define NI_MAXSERV 32
#endif
+#ifndef INVALID_SOCKET /* MS defines this */
+#define INVALID_SOCKET (-1)
+#endif
+
/* XXX There's a problem here: *static* functions are not supposed to have
a Py prefix (or use CapitalizedWords). Later... */
@@ -439,11 +443,6 @@ static PyObject *socket_herror;
static PyObject *socket_gaierror;
static PyObject *socket_timeout;
-#ifdef RISCOS
-/* Global variable which is !=0 if Python is running in a RISC OS taskwindow */
-static int taskwindow;
-#endif
-
/* A forward reference to the socket type object.
The sock_type variable contains pointers to various functions,
some of which call new_sockobject(), which uses sock_type, so
@@ -473,6 +472,17 @@ select_error(void)
return NULL;
}
+#ifdef MS_WINDOWS
+#ifndef WSAEAGAIN
+#define WSAEAGAIN WSAEWOULDBLOCK
+#endif
+#define CHECK_ERRNO(expected) \
+ (WSAGetLastError() == WSA ## expected)
+#else
+#define CHECK_ERRNO(expected) \
+ (errno == expected)
+#endif
+
/* Convenience function to raise an error according to errno
and return a NULL pointer from a function. */
@@ -524,18 +534,6 @@ set_error(void)
}
#endif
-#if defined(RISCOS)
- if (_inet_error.errnum != NULL) {
- PyObject *v;
- v = Py_BuildValue("(is)", errno, _inet_err());
- if (v != NULL) {
- PyErr_SetObject(socket_error, v);
- Py_DECREF(v);
- }
- return NULL;
- }
-#endif
-
return PyErr_SetFromErrno(socket_error);
}
@@ -612,19 +610,17 @@ sendsegmented(int sock_fd, char *buf, int len, int flags)
static int
internal_setblocking(PySocketSockObject *s, int block)
{
-#ifndef RISCOS
#ifndef MS_WINDOWS
int delay_flag;
#endif
+#ifdef SOCK_NONBLOCK
+ if (block)
+ s->sock_type &= (~SOCK_NONBLOCK);
+ else
+ s->sock_type |= SOCK_NONBLOCK;
#endif
Py_BEGIN_ALLOW_THREADS
-#ifdef __BEOS__
- block = !block;
- setsockopt(s->sock_fd, SOL_SOCKET, SO_NONBLOCK,
- (void *)(&block), sizeof(int));
-#else
-#ifndef RISCOS
#ifndef MS_WINDOWS
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
block = !block;
@@ -644,11 +640,6 @@ internal_setblocking(PySocketSockObject *s, int block)
block = !block;
ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block);
#endif /* MS_WINDOWS */
-#else /* RISCOS */
- block = !block;
- socketioctl(s->sock_fd, FIONBIO, (u_long*)&block);
-#endif /* RISCOS */
-#endif /* __BEOS__ */
Py_END_ALLOW_THREADS
/* Since these don't return anything */
@@ -661,7 +652,7 @@ internal_setblocking(PySocketSockObject *s, int block)
after they've reacquired the interpreter lock.
Returns 1 on timeout, -1 on error, 0 otherwise. */
static int
-internal_select(PySocketSockObject *s, int writing)
+internal_select_ex(PySocketSockObject *s, int writing, double interval)
{
int n;
@@ -673,6 +664,10 @@ internal_select(PySocketSockObject *s, int writing)
if (s->sock_fd < 0)
return 0;
+ /* Handling this condition here simplifies the select loops */
+ if (interval < 0.0)
+ return 1;
+
/* Prefer poll, if available, since you can poll() any fd
* which can't be done with select(). */
#ifdef HAVE_POLL
@@ -684,7 +679,7 @@ internal_select(PySocketSockObject *s, int writing)
pollfd.events = writing ? POLLOUT : POLLIN;
/* s->sock_timeout is in seconds, timeout in ms */
- timeout = (int)(s->sock_timeout * 1000 + 0.5);
+ timeout = (int)(interval * 1000 + 0.5);
n = poll(&pollfd, 1, timeout);
}
#else
@@ -692,16 +687,18 @@ internal_select(PySocketSockObject *s, int writing)
/* Construct the arguments to select */
fd_set fds;
struct timeval tv;
- tv.tv_sec = (int)s->sock_timeout;
- tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+ tv.tv_sec = (int)interval;
+ tv.tv_usec = (int)((interval - tv.tv_sec) * 1e6);
FD_ZERO(&fds);
FD_SET(s->sock_fd, &fds);
/* See if the socket is ready */
if (writing)
- n = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
+ n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
+ NULL, &fds, NULL, &tv);
else
- n = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+ n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
+ &fds, NULL, NULL, &tv);
}
#endif
@@ -712,32 +709,78 @@ internal_select(PySocketSockObject *s, int writing)
return 0;
}
+static int
+internal_select(PySocketSockObject *s, int writing)
+{
+ return internal_select_ex(s, writing, s->sock_timeout);
+}
+
+/*
+ Two macros for automatic retry of select() in case of false positives
+ (for example, select() could indicate a socket is ready for reading
+ but the data then discarded by the OS because of a wrong checksum).
+ Here is an example of use:
+
+ BEGIN_SELECT_LOOP(s)
+ Py_BEGIN_ALLOW_THREADS
+ timeout = internal_select_ex(s, 0, interval);
+ if (!timeout)
+ outlen = recv(s->sock_fd, cbuf, len, flags);
+ Py_END_ALLOW_THREADS
+ if (timeout == 1) {
+ PyErr_SetString(socket_timeout, "timed out");
+ return -1;
+ }
+ END_SELECT_LOOP(s)
+*/
+
+#define BEGIN_SELECT_LOOP(s) \
+ { \
+ _PyTime_timeval now, deadline = {0, 0}; \
+ double interval = s->sock_timeout; \
+ int has_timeout = s->sock_timeout > 0.0; \
+ if (has_timeout) { \
+ _PyTime_gettimeofday(&now); \
+ deadline = now; \
+ _PyTime_ADD_SECONDS(deadline, s->sock_timeout); \
+ } \
+ while (1) { \
+ errno = 0; \
+
+#define END_SELECT_LOOP(s) \
+ if (!has_timeout || \
+ (!CHECK_ERRNO(EWOULDBLOCK) && !CHECK_ERRNO(EAGAIN))) \
+ break; \
+ _PyTime_gettimeofday(&now); \
+ interval = _PyTime_INTERVAL(now, deadline); \
+ } \
+ } \
+
/* Initialize a new socket object. */
static double defaulttimeout = -1.0; /* Default timeout for new sockets */
-PyMODINIT_FUNC
+static void
init_sockobject(PySocketSockObject *s,
SOCKET_T fd, int family, int type, int proto)
{
-#ifdef RISCOS
- int block = 1;
-#endif
s->sock_fd = fd;
s->sock_family = family;
s->sock_type = type;
s->sock_proto = proto;
- s->sock_timeout = defaulttimeout;
s->errorhandler = &set_error;
-
- if (defaulttimeout >= 0.0)
- internal_setblocking(s, 0);
-
-#ifdef RISCOS
- if (taskwindow)
- socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
+#ifdef SOCK_NONBLOCK
+ if (type & SOCK_NONBLOCK)
+ s->sock_timeout = 0.0;
+ else
#endif
+ {
+ s->sock_timeout = defaulttimeout;
+ if (defaulttimeout >= 0.0)
+ internal_setblocking(s, 0);
+ }
+
}
@@ -909,7 +952,7 @@ makeipaddr(struct sockaddr *addr, int addrlen)
set_gaierror(error);
return NULL;
}
- return PyString_FromString(buf);
+ return PyUnicode_FromString(buf);
}
@@ -953,7 +996,7 @@ makebdaddr(bdaddr_t *bdaddr)
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
- return PyString_FromString(buf);
+ return PyUnicode_FromString(buf);
}
#endif
@@ -965,7 +1008,7 @@ makebdaddr(bdaddr_t *bdaddr)
/*ARGSUSED*/
static PyObject *
-makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
+makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
{
if (addrlen == 0) {
/* No address -- may be recvfrom() from known socket */
@@ -973,11 +1016,6 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
return Py_None;
}
-#ifdef __BEOS__
- /* XXX: BeOS version of accept() doesn't set family correctly */
- addr->sa_family = AF_INET;
-#endif
-
switch (addr->sa_family) {
case AF_INET:
@@ -1000,14 +1038,13 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
#ifdef linux
if (a->sun_path[0] == 0) { /* Linux abstract namespace */
addrlen -= offsetof(struct sockaddr_un, sun_path);
- return PyString_FromStringAndSize(a->sun_path,
- addrlen);
+ return PyBytes_FromStringAndSize(a->sun_path, addrlen);
}
else
#endif /* linux */
{
/* regular NULL-terminated string */
- return PyString_FromString(a->sun_path);
+ return PyUnicode_FromString(a->sun_path);
}
}
#endif /* AF_UNIX */
@@ -1110,7 +1147,7 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0)
ifname = ifr.ifr_name;
}
- return Py_BuildValue("shbhs#",
+ return Py_BuildValue("shbhy#",
ifname,
ntohs(a->sll_protocol),
a->sll_pkttype,
@@ -1157,8 +1194,8 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
default:
/* If we don't know the address family, don't raise an
- exception -- return it as a tuple. */
- return Py_BuildValue("is#",
+ exception -- return it as an (int, bytes) tuple. */
+ return Py_BuildValue("iy#",
addr->sa_family,
addr->sa_data,
sizeof(addr->sa_data));
@@ -1184,7 +1221,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
struct sockaddr_un* addr;
char *path;
int len;
- if (!PyArg_Parse(args, "t#", &path, &len))
+ if (!PyArg_Parse(args, "s#", &path, &len))
return 0;
addr = (struct sockaddr_un*)addr_ret;
@@ -1372,9 +1409,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
{
struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret;
#if defined(__NetBSD__) || defined(__DragonFly__)
- char *straddr = PyBytes_AS_STRING(args);
+ char *straddr = PyBytes_AS_STRING(args);
- _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
+ _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
if (straddr == NULL) {
PyErr_SetString(socket_error, "getsockaddrarg: "
"wrong format");
@@ -1401,12 +1438,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
addr = (struct sockaddr_sco *)addr_ret;
_BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
- straddr = PyString_AsString(args);
- if (straddr == NULL) {
+ if (!PyBytes_Check(args)) {
PyErr_SetString(socket_error, "getsockaddrarg: "
"wrong format");
return 0;
}
+ straddr = PyBytes_AS_STRING(args);
if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0)
return 0;
@@ -1441,7 +1478,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
Py_TYPE(args)->tp_name);
return 0;
}
- if (!PyArg_ParseTuple(args, "si|iis#", &interfaceName,
+ if (!PyArg_ParseTuple(args, "si|iiy#", &interfaceName,
&protoNumber, &pkttype, &hatype,
&haddr, &halen))
return 0;
@@ -1630,61 +1667,48 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
}
-/* s.accept() method */
+/* s._accept() -> (fd, address) */
static PyObject *
sock_accept(PySocketSockObject *s)
{
sock_addr_t addrbuf;
- SOCKET_T newfd;
+ SOCKET_T newfd = INVALID_SOCKET;
socklen_t addrlen;
PyObject *sock = NULL;
PyObject *addr = NULL;
PyObject *res = NULL;
int timeout;
-
if (!getsockaddrlen(s, &addrlen))
return NULL;
memset(&addrbuf, 0, addrlen);
-#ifdef MS_WINDOWS
- newfd = INVALID_SOCKET;
-#else
- newfd = -1;
-#endif
-
if (!IS_SELECTABLE(s))
return select_error();
+ BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS
- timeout = internal_select(s, 0);
- if (!timeout)
+ timeout = internal_select_ex(s, 0, interval);
+ if (!timeout) {
newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
+ }
Py_END_ALLOW_THREADS
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return NULL;
}
+ END_SELECT_LOOP(s)
-#ifdef MS_WINDOWS
if (newfd == INVALID_SOCKET)
-#else
- if (newfd < 0)
-#endif
return s->errorhandler();
- /* Create the new object with unspecified family,
- to avoid calls to bind() etc. on it. */
- sock = (PyObject *) new_sockobject(newfd,
- s->sock_family,
- s->sock_type,
- s->sock_proto);
-
+ sock = PyLong_FromSocket_t(newfd);
if (sock == NULL) {
SOCKETCLOSE(newfd);
goto finally;
}
+
addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
addrlen, s->sock_proto);
if (addr == NULL)
@@ -1699,11 +1723,11 @@ finally:
}
PyDoc_STRVAR(accept_doc,
-"accept() -> (socket object, address info)\n\
+"_accept() -> (integer, address info)\n\
\n\
-Wait for an incoming connection. Return a new socket representing the\n\
-connection, and the address of the client. For IP sockets, the address\n\
-info is a pair (hostaddr, port).");
+Wait for an incoming connection. Return a new socket file descriptor\n\
+representing the connection, and the address of the client.\n\
+For IP sockets, the address info is a pair (hostaddr, port).");
/* s.setblocking(flag) method. Argument:
False -- non-blocking mode; same as settimeout(0)
@@ -1715,7 +1739,7 @@ sock_setblocking(PySocketSockObject *s, PyObject *arg)
{
int block;
- block = PyInt_AsLong(arg);
+ block = PyLong_AsLong(arg);
if (block == -1 && PyErr_Occurred())
return NULL;
@@ -1791,30 +1815,6 @@ Returns the timeout in seconds (float) associated with socket \n\
operations. A timeout of None indicates that timeouts on socket \n\
operations are disabled.");
-#ifdef RISCOS
-/* s.sleeptaskw(1 | 0) method */
-
-static PyObject *
-sock_sleeptaskw(PySocketSockObject *s,PyObject *arg)
-{
- int block;
- block = PyInt_AsLong(arg);
- if (block == -1 && PyErr_Occurred())
- return NULL;
- Py_BEGIN_ALLOW_THREADS
- socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
- Py_END_ALLOW_THREADS
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-PyDoc_STRVAR(sleeptaskw_doc,
-"sleeptaskw(flag)\n\
-\n\
-Allow sleeps in taskwindows.");
-#endif
-
-
/* s.setsockopt() method.
With an integer third argument, sets an integer option.
With a string third argument, sets an option from a buffer;
@@ -1837,7 +1837,7 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args)
}
else {
PyErr_Clear();
- if (!PyArg_ParseTuple(args, "iis#:setsockopt",
+ if (!PyArg_ParseTuple(args, "iiy#:setsockopt",
&level, &optname, &buf, &buflen))
return NULL;
}
@@ -1869,12 +1869,6 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
PyObject *buf;
socklen_t buflen = 0;
-#ifdef __BEOS__
- /* We have incomplete socket support. */
- PyErr_SetString(socket_error, "getsockopt not supported");
- return NULL;
-#else
-
if (!PyArg_ParseTuple(args, "ii|i:getsockopt",
&level, &optname, &buflen))
return NULL;
@@ -1886,7 +1880,7 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
(void *)&flag, &flagsize);
if (res < 0)
return s->errorhandler();
- return PyInt_FromLong(flag);
+ return PyLong_FromLong(flag);
}
#ifdef __VMS
/* socklen_t is unsigned so no negative test is needed,
@@ -1899,18 +1893,17 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
"getsockopt buflen out of range");
return NULL;
}
- buf = PyString_FromStringAndSize((char *)NULL, buflen);
+ buf = PyBytes_FromStringAndSize((char *)NULL, buflen);
if (buf == NULL)
return NULL;
res = getsockopt(s->sock_fd, level, optname,
- (void *)PyString_AS_STRING(buf), &buflen);
+ (void *)PyBytes_AS_STRING(buf), &buflen);
if (res < 0) {
Py_DECREF(buf);
return s->errorhandler();
}
- _PyString_Resize(&buf, buflen);
+ _PyBytes_Resize(&buf, buflen);
return buf;
-#endif /* __BEOS__ */
}
PyDoc_STRVAR(getsockopt_doc,
@@ -1973,6 +1966,21 @@ PyDoc_STRVAR(close_doc,
\n\
Close the socket. It cannot be used after this call.");
+static PyObject *
+sock_detach(PySocketSockObject *s)
+{
+ SOCKET_T fd = s->sock_fd;
+ s->sock_fd = -1;
+ return PyLong_FromSocket_t(fd);
+}
+
+PyDoc_STRVAR(detach_doc,
+"detach()\n\
+\n\
+Close the socket object without closing the underlying file descriptor.\
+The object cannot be used after this call, but the file descriptor\
+can be reused for other purposes. The file descriptor is returned.");
+
static int
internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
int *timeoutp)
@@ -1997,13 +2005,14 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
FD_SET(s->sock_fd, &fds);
FD_ZERO(&fds_exc);
FD_SET(s->sock_fd, &fds_exc);
- res = select(s->sock_fd+1, NULL, &fds, &fds_exc, &tv);
+ res = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
+ NULL, &fds, &fds_exc, &tv);
if (res == 0) {
res = WSAEWOULDBLOCK;
timeout = 1;
} else if (res > 0) {
if (FD_ISSET(s->sock_fd, &fds))
- /* The socket is in the writeable set - this
+ /* The socket is in the writable set - this
means connected */
res = 0;
else {
@@ -2119,7 +2128,7 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
return NULL;
#endif
- return PyInt_FromLong((long) res);
+ return PyLong_FromLong((long) res);
}
PyDoc_STRVAR(connect_ex_doc,
@@ -2134,11 +2143,7 @@ instead of raising an exception when an error occurs.");
static PyObject *
sock_fileno(PySocketSockObject *s)
{
-#if SIZEOF_SOCKET_T <= SIZEOF_LONG
- return PyInt_FromLong((long) s->sock_fd);
-#else
- return PyLong_FromLongLong((PY_LONG_LONG)s->sock_fd);
-#endif
+ return PyLong_FromSocket_t(s->sock_fd);
}
PyDoc_STRVAR(fileno_doc,
@@ -2147,35 +2152,6 @@ PyDoc_STRVAR(fileno_doc,
Return the integer file descriptor of the socket.");
-#ifndef NO_DUP
-/* s.dup() method */
-
-static PyObject *
-sock_dup(PySocketSockObject *s)
-{
- SOCKET_T newfd;
- PyObject *sock;
-
- newfd = dup(s->sock_fd);
- if (newfd < 0)
- return s->errorhandler();
- sock = (PyObject *) new_sockobject(newfd,
- s->sock_family,
- s->sock_type,
- s->sock_proto);
- if (sock == NULL)
- SOCKETCLOSE(newfd);
- return sock;
-}
-
-PyDoc_STRVAR(dup_doc,
-"dup() -> socket object\n\
-\n\
-Return a new socket object connected to the same system resource.");
-
-#endif
-
-
/* s.getsockname() method */
static PyObject *
@@ -2243,7 +2219,7 @@ sock_listen(PySocketSockObject *s, PyObject *arg)
int backlog;
int res;
- backlog = PyInt_AsLong(arg);
+ backlog = PyLong_AsLong(arg);
if (backlog == -1 && PyErr_Occurred())
return NULL;
Py_BEGIN_ALLOW_THREADS
@@ -2268,69 +2244,6 @@ unaccepted connections that the system will allow before refusing new\n\
connections.");
-#ifndef NO_DUP
-/* s.makefile(mode) method.
- Create a new open file object referring to a dupped version of
- the socket's file descriptor. (The dup() call is necessary so
- that the open file and socket objects may be closed independent
- of each other.)
- The mode argument specifies 'r' or 'w' passed to fdopen(). */
-
-static PyObject *
-sock_makefile(PySocketSockObject *s, PyObject *args)
-{
- extern int fclose(FILE *);
- char *mode = "r";
- int bufsize = -1;
-#ifdef MS_WIN32
- Py_intptr_t fd;
-#else
- int fd;
-#endif
- FILE *fp;
- PyObject *f;
-#ifdef __VMS
- char *mode_r = "r";
- char *mode_w = "w";
-#endif
-
- if (!PyArg_ParseTuple(args, "|si:makefile", &mode, &bufsize))
- return NULL;
-#ifdef __VMS
- if (strcmp(mode,"rb") == 0) {
- mode = mode_r;
- }
- else {
- if (strcmp(mode,"wb") == 0) {
- mode = mode_w;
- }
- }
-#endif
-#ifdef MS_WIN32
- if (((fd = _open_osfhandle(s->sock_fd, _O_BINARY)) < 0) ||
- ((fd = dup(fd)) < 0) || ((fp = fdopen(fd, mode)) == NULL))
-#else
- if ((fd = dup(s->sock_fd)) < 0 || (fp = fdopen(fd, mode)) == NULL)
-#endif
- {
- if (fd >= 0)
- SOCKETCLOSE(fd);
- return s->errorhandler();
- }
- f = PyFile_FromFile(fp, "<socket>", mode, fclose);
- if (f != NULL)
- PyFile_SetBufSize(f, bufsize);
- return f;
-}
-
-PyDoc_STRVAR(makefile_doc,
-"makefile([mode[, buffersize]]) -> file object\n\
-\n\
-Return a regular file object corresponding to the socket.\n\
-The mode and buffersize arguments are as for the built-in open() function.");
-
-#endif /* NO_DUP */
-
/*
* This is the guts of the recv() and recv_into() methods, which reads into a
* char buffer. If you have any inc/dec ref to do to the objects that contain
@@ -2339,10 +2252,11 @@ The mode and buffersize arguments are as for the built-in open() function.");
* also possible that we return a number of bytes smaller than the request
* bytes.
*/
-static ssize_t
-sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
+
+static Py_ssize_t
+sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags)
{
- ssize_t outlen = -1;
+ Py_ssize_t outlen = -1;
int timeout;
#ifdef __VMS
int remaining;
@@ -2353,10 +2267,15 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
select_error();
return -1;
}
+ if (len == 0) {
+ /* If 0 bytes were requested, do nothing. */
+ return 0;
+ }
#ifndef __VMS
+ BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS
- timeout = internal_select(s, 0);
+ timeout = internal_select_ex(s, 0, interval);
if (!timeout)
outlen = recv(s->sock_fd, cbuf, len, flags);
Py_END_ALLOW_THREADS
@@ -2365,6 +2284,7 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
PyErr_SetString(socket_timeout, "timed out");
return -1;
}
+ END_SELECT_LOOP(s)
if (outlen < 0) {
/* Note: the call to errorhandler() ALWAYS indirectly returned
NULL, so ignore its return value */
@@ -2386,16 +2306,18 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
segment = remaining;
}
+ BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS
- timeout = internal_select(s, 0);
+ timeout = internal_select_ex(s, 0, interval);
if (!timeout)
nread = recv(s->sock_fd, read_buf, segment, flags);
Py_END_ALLOW_THREADS
-
if (timeout == 1) {
PyErr_SetString(socket_timeout, "timed out");
return -1;
}
+ END_SELECT_LOOP(s)
+
if (nread < 0) {
s->errorhandler();
return -1;
@@ -2420,11 +2342,11 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
static PyObject *
sock_recv(PySocketSockObject *s, PyObject *args)
{
- int recvlen, flags = 0;
- ssize_t outlen;
+ Py_ssize_t recvlen, outlen;
+ int flags = 0;
PyObject *buf;
- if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
+ if (!PyArg_ParseTuple(args, "n|i:recv", &recvlen, &flags))
return NULL;
if (recvlen < 0) {
@@ -2434,12 +2356,12 @@ sock_recv(PySocketSockObject *s, PyObject *args)
}
/* Allocate a new string. */
- buf = PyString_FromStringAndSize((char *) 0, recvlen);
+ buf = PyBytes_FromStringAndSize((char *) 0, recvlen);
if (buf == NULL)
return NULL;
/* Call the guts */
- outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags);
+ outlen = sock_recv_guts(s, PyBytes_AS_STRING(buf), recvlen, flags);
if (outlen < 0) {
/* An error occurred, release the string and return an
error. */
@@ -2449,9 +2371,7 @@ sock_recv(PySocketSockObject *s, PyObject *args)
if (outlen != recvlen) {
/* We did not read as many bytes as we anticipated, resize the
string if possible and be successful. */
- if (_PyString_Resize(&buf, outlen) < 0)
- /* Oopsy, not so successful after all. */
- return NULL;
+ _PyBytes_Resize(&buf, outlen);
}
return buf;
@@ -2473,22 +2393,23 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
- int recvlen = 0, flags = 0;
- ssize_t readlen;
- Py_buffer buf;
- Py_ssize_t buflen;
+ int flags = 0;
+ Py_buffer pbuf;
+ char *buf;
+ Py_ssize_t buflen, readlen, recvlen = 0;
/* Get the buffer's memory */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recv_into", kwlist,
- &buf, &recvlen, &flags))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recv_into", kwlist,
+ &pbuf, &recvlen, &flags))
return NULL;
- buflen = buf.len;
- assert(buf.buf != 0 && buflen > 0);
+ buf = pbuf.buf;
+ buflen = pbuf.len;
if (recvlen < 0) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(PyExc_ValueError,
"negative buffersize in recv_into");
- goto error;
+ return NULL;
}
if (recvlen == 0) {
/* If nbytes was not specified, use the buffer's length */
@@ -2497,26 +2418,24 @@ sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
/* Check if the buffer is large enough */
if (buflen < recvlen) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(PyExc_ValueError,
"buffer too small for requested bytes");
- goto error;
+ return NULL;
}
/* Call the guts */
- readlen = sock_recv_guts(s, buf.buf, recvlen, flags);
+ readlen = sock_recv_guts(s, buf, recvlen, flags);
if (readlen < 0) {
/* Return an error. */
- goto error;
+ PyBuffer_Release(&pbuf);
+ return NULL;
}
- PyBuffer_Release(&buf);
+ PyBuffer_Release(&pbuf);
/* Return the number of bytes read. Note that we do not do anything
special here in the case that readlen < recvlen. */
- return PyInt_FromSsize_t(readlen);
-
-error:
- PyBuffer_Release(&buf);
- return NULL;
+ return PyLong_FromSsize_t(readlen);
}
PyDoc_STRVAR(recv_into_doc,
@@ -2540,13 +2459,13 @@ See recv() for documentation about the flags.");
* 'addr' is a return value for the address object. Note that you must decref
* it yourself.
*/
-static ssize_t
-sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
+static Py_ssize_t
+sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags,
PyObject** addr)
{
sock_addr_t addrbuf;
int timeout;
- ssize_t n = -1;
+ Py_ssize_t n = -1;
socklen_t addrlen;
*addr = NULL;
@@ -2559,9 +2478,10 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
return -1;
}
+ BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS
memset(&addrbuf, 0, addrlen);
- timeout = internal_select(s, 0);
+ timeout = internal_select_ex(s, 0, interval);
if (!timeout) {
#ifndef MS_WINDOWS
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
@@ -2582,6 +2502,7 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
PyErr_SetString(socket_timeout, "timed out");
return -1;
}
+ END_SELECT_LOOP(s)
if (n < 0) {
s->errorhandler();
return -1;
@@ -2602,10 +2523,10 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
PyObject *buf = NULL;
PyObject *addr = NULL;
PyObject *ret = NULL;
- int recvlen, flags = 0;
- ssize_t outlen;
+ int flags = 0;
+ Py_ssize_t recvlen, outlen;
- if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
+ if (!PyArg_ParseTuple(args, "n|i:recvfrom", &recvlen, &flags))
return NULL;
if (recvlen < 0) {
@@ -2614,11 +2535,11 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
return NULL;
}
- buf = PyString_FromStringAndSize((char *) 0, recvlen);
+ buf = PyBytes_FromStringAndSize((char *) 0, recvlen);
if (buf == NULL)
return NULL;
- outlen = sock_recvfrom_guts(s, PyString_AS_STRING(buf),
+ outlen = sock_recvfrom_guts(s, PyBytes_AS_STRING(buf),
recvlen, flags, &addr);
if (outlen < 0) {
goto finally;
@@ -2627,7 +2548,7 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
if (outlen != recvlen) {
/* We did not read as many bytes as we anticipated, resize the
string if possible and be successful. */
- if (_PyString_Resize(&buf, outlen) < 0)
+ if (_PyBytes_Resize(&buf, outlen) < 0)
/* Oopsy, not so successful after all. */
goto finally;
}
@@ -2653,45 +2574,44 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
{
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
- int recvlen = 0, flags = 0;
- ssize_t readlen;
- Py_buffer buf;
- int buflen;
+ int flags = 0;
+ Py_buffer pbuf;
+ char *buf;
+ Py_ssize_t readlen, buflen, recvlen = 0;
PyObject *addr = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recvfrom_into",
- kwlist, &buf,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recvfrom_into",
+ kwlist, &pbuf,
&recvlen, &flags))
return NULL;
- buflen = buf.len;
- assert(buf.buf != 0 && buflen > 0);
+ buf = pbuf.buf;
+ buflen = pbuf.len;
+ assert(buf != 0 && buflen > 0);
if (recvlen < 0) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(PyExc_ValueError,
"negative buffersize in recvfrom_into");
- goto error;
+ return NULL;
}
if (recvlen == 0) {
/* If nbytes was not specified, use the buffer's length */
recvlen = buflen;
}
- readlen = sock_recvfrom_guts(s, buf.buf, recvlen, flags, &addr);
+ readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
if (readlen < 0) {
+ PyBuffer_Release(&pbuf);
/* Return an error */
- goto error;
+ Py_XDECREF(addr);
+ return NULL;
}
- PyBuffer_Release(&buf);
+ PyBuffer_Release(&pbuf);
/* Return the number of bytes read and the address. Note that we do
not do anything special here in the case that readlen < recvlen. */
- return Py_BuildValue("lN", readlen, addr);
-
-error:
- Py_XDECREF(addr);
- PyBuffer_Release(&buf);
- return NULL;
+ return Py_BuildValue("nN", readlen, addr);
}
PyDoc_STRVAR(recvfrom_into_doc,
@@ -2706,10 +2626,11 @@ static PyObject *
sock_send(PySocketSockObject *s, PyObject *args)
{
char *buf;
- int len, n = -1, flags = 0, timeout;
+ Py_ssize_t len, n = -1;
+ int flags = 0, timeout;
Py_buffer pbuf;
- if (!PyArg_ParseTuple(args, "s*|i:send", &pbuf, &flags))
+ if (!PyArg_ParseTuple(args, "y*|i:send", &pbuf, &flags))
return NULL;
if (!IS_SELECTABLE(s)) {
@@ -2719,8 +2640,9 @@ sock_send(PySocketSockObject *s, PyObject *args)
buf = pbuf.buf;
len = pbuf.len;
+ BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS
- timeout = internal_select(s, 1);
+ timeout = internal_select_ex(s, 1, interval);
if (!timeout)
#ifdef __VMS
n = sendsegmented(s->sock_fd, buf, len, flags);
@@ -2728,16 +2650,17 @@ sock_send(PySocketSockObject *s, PyObject *args)
n = send(s->sock_fd, buf, len, flags);
#endif
Py_END_ALLOW_THREADS
-
- PyBuffer_Release(&pbuf);
-
if (timeout == 1) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(socket_timeout, "timed out");
return NULL;
}
+ END_SELECT_LOOP(s)
+
+ PyBuffer_Release(&pbuf);
if (n < 0)
return s->errorhandler();
- return PyInt_FromLong((long)n);
+ return PyLong_FromSsize_t(n);
}
PyDoc_STRVAR(send_doc,
@@ -2754,10 +2677,11 @@ static PyObject *
sock_sendall(PySocketSockObject *s, PyObject *args)
{
char *buf;
- int len, n = -1, flags = 0, timeout, saved_errno;
+ Py_ssize_t len, n = -1;
+ int flags = 0, timeout, saved_errno;
Py_buffer pbuf;
- if (!PyArg_ParseTuple(args, "s*|i:sendall", &pbuf, &flags))
+ if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags))
return NULL;
buf = pbuf.buf;
len = pbuf.len;
@@ -2829,23 +2753,24 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
Py_buffer pbuf;
PyObject *addro;
char *buf;
- Py_ssize_t len;
+ Py_ssize_t len, arglen;
sock_addr_t addrbuf;
int addrlen, n = -1, flags, timeout;
- int arglen;
flags = 0;
arglen = PyTuple_Size(args);
- switch(arglen) {
+ switch (arglen) {
case 2:
- PyArg_ParseTuple(args, "s*O:sendto", &pbuf, &addro);
+ PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro);
break;
case 3:
- PyArg_ParseTuple(args, "s*iO:sendto", &pbuf, &flags, &addro);
+ PyArg_ParseTuple(args, "y*iO:sendto",
+ &pbuf, &flags, &addro);
break;
default:
- PyErr_Format(PyExc_TypeError, "sendto() takes 2 or 3"
- " arguments (%d given)", arglen);
+ PyErr_Format(PyExc_TypeError,
+ "sendto() takes 2 or 3 arguments (%d given)",
+ arglen);
}
if (PyErr_Occurred())
return NULL;
@@ -2863,20 +2788,23 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
return NULL;
}
+ BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS
- timeout = internal_select(s, 1);
+ timeout = internal_select_ex(s, 1, interval);
if (!timeout)
n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
Py_END_ALLOW_THREADS
- PyBuffer_Release(&pbuf);
if (timeout == 1) {
+ PyBuffer_Release(&pbuf);
PyErr_SetString(socket_timeout, "timed out");
return NULL;
}
+ END_SELECT_LOOP(s)
+ PyBuffer_Release(&pbuf);
if (n < 0)
return s->errorhandler();
- return PyInt_FromLong((long)n);
+ return PyLong_FromSsize_t(n);
}
PyDoc_STRVAR(sendto_doc,
@@ -2894,7 +2822,7 @@ sock_shutdown(PySocketSockObject *s, PyObject *arg)
int how;
int res;
- how = PyInt_AsLong(arg);
+ how = PyLong_AsLong(arg);
if (how == -1 && PyErr_Occurred())
return NULL;
Py_BEGIN_ALLOW_THREADS
@@ -2960,7 +2888,7 @@ SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval).");
/* List of methods for socket objects */
static PyMethodDef sock_methods[] = {
- {"accept", (PyCFunction)sock_accept, METH_NOARGS,
+ {"_accept", (PyCFunction)sock_accept, METH_NOARGS,
accept_doc},
{"bind", (PyCFunction)sock_bind, METH_O,
bind_doc},
@@ -2970,10 +2898,8 @@ static PyMethodDef sock_methods[] = {
connect_doc},
{"connect_ex", (PyCFunction)sock_connect_ex, METH_O,
connect_ex_doc},
-#ifndef NO_DUP
- {"dup", (PyCFunction)sock_dup, METH_NOARGS,
- dup_doc},
-#endif
+ {"detach", (PyCFunction)sock_detach, METH_NOARGS,
+ detach_doc},
{"fileno", (PyCFunction)sock_fileno, METH_NOARGS,
fileno_doc},
#ifdef HAVE_GETPEERNAME
@@ -2990,10 +2916,6 @@ static PyMethodDef sock_methods[] = {
#endif
{"listen", (PyCFunction)sock_listen, METH_O,
listen_doc},
-#ifndef NO_DUP
- {"makefile", (PyCFunction)sock_makefile, METH_VARARGS,
- makefile_doc},
-#endif
{"recv", (PyCFunction)sock_recv, METH_VARARGS,
recv_doc},
{"recv_into", (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS,
@@ -3018,10 +2940,6 @@ static PyMethodDef sock_methods[] = {
setsockopt_doc},
{"shutdown", (PyCFunction)sock_shutdown, METH_O,
shutdown_doc},
-#ifdef RISCOS
- {"sleeptaskw", (PyCFunction)sock_sleeptaskw, METH_O,
- sleeptaskw_doc},
-#endif
{NULL, NULL} /* sentinel */
};
@@ -3040,8 +2958,20 @@ static PyMemberDef sock_memberlist[] = {
static void
sock_dealloc(PySocketSockObject *s)
{
- if (s->sock_fd != -1)
+ if (s->sock_fd != -1) {
+ PyObject *exc, *val, *tb;
+ Py_ssize_t old_refcount = Py_REFCNT(s);
+ ++Py_REFCNT(s);
+ PyErr_Fetch(&exc, &val, &tb);
+ if (PyErr_WarnFormat(PyExc_ResourceWarning, 1,
+ "unclosed %R", s))
+ /* Spurious errors can appear at shutdown */
+ if (PyErr_ExceptionMatches(PyExc_Warning))
+ PyErr_WriteUnraisable((PyObject *) s);
+ PyErr_Restore(exc, val, tb);
(void) SOCKETCLOSE(s->sock_fd);
+ Py_REFCNT(s) = old_refcount;
+ }
Py_TYPE(s)->tp_free((PyObject *)s);
}
@@ -3049,7 +2979,6 @@ sock_dealloc(PySocketSockObject *s)
static PyObject *
sock_repr(PySocketSockObject *s)
{
- char buf[512];
#if SIZEOF_SOCKET_T > SIZEOF_LONG
if (s->sock_fd > LONG_MAX) {
/* this can occur on Win64, and actually there is a special
@@ -3061,13 +2990,11 @@ sock_repr(PySocketSockObject *s)
return NULL;
}
#endif
- PyOS_snprintf(
- buf, sizeof(buf),
- "<socket object, fd=%ld, family=%d, type=%d, protocol=%d>",
+ return PyUnicode_FromFormat(
+ "<socket object, fd=%ld, family=%d, type=%d, proto=%d>",
(long)s->sock_fd, s->sock_family,
s->sock_type,
s->sock_proto);
- return PyString_FromString(buf);
}
@@ -3095,27 +3022,35 @@ static int
sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
{
PySocketSockObject *s = (PySocketSockObject *)self;
- SOCKET_T fd;
+ PyObject *fdobj = NULL;
+ SOCKET_T fd = INVALID_SOCKET;
int family = AF_INET, type = SOCK_STREAM, proto = 0;
- static char *keywords[] = {"family", "type", "proto", 0};
+ static char *keywords[] = {"family", "type", "proto", "fileno", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds,
- "|iii:socket", keywords,
- &family, &type, &proto))
+ "|iiiO:socket", keywords,
+ &family, &type, &proto, &fdobj))
return -1;
- Py_BEGIN_ALLOW_THREADS
- fd = socket(family, type, proto);
- Py_END_ALLOW_THREADS
+ if (fdobj != NULL && fdobj != Py_None) {
+ fd = PyLong_AsSocket_t(fdobj);
+ if (fd == (SOCKET_T)(-1) && PyErr_Occurred())
+ return -1;
+ if (fd == INVALID_SOCKET) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't use invalid socket value");
+ return -1;
+ }
+ }
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ fd = socket(family, type, proto);
+ Py_END_ALLOW_THREADS
-#ifdef MS_WINDOWS
- if (fd == INVALID_SOCKET)
-#else
- if (fd < 0)
-#endif
- {
- set_error();
- return -1;
+ if (fd == INVALID_SOCKET) {
+ set_error();
+ return -1;
+ }
}
init_sockobject(s, fd, family, type, proto);
@@ -3135,7 +3070,7 @@ static PyTypeObject sock_type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_compare */
+ 0, /* tp_reserved */
(reprfunc)sock_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -3175,6 +3110,31 @@ static PyTypeObject sock_type = {
static PyObject *
socket_gethostname(PyObject *self, PyObject *unused)
{
+#ifdef MS_WINDOWS
+ /* Don't use winsock's gethostname, as this returns the ANSI
+ version of the hostname, whereas we need a Unicode string.
+ Otherwise, gethostname apparently also returns the DNS name. */
+ wchar_t buf[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD size = sizeof(buf) / sizeof(wchar_t);
+ PyObject *result;
+ if (!GetComputerNameExW(ComputerNamePhysicalDnsHostname, buf, &size)) {
+ if (GetLastError() == ERROR_MORE_DATA) {
+ /* MSDN says this may occur "because DNS allows longer names */
+ if (size == 0) /* XXX: I'm not sure how to handle this */
+ return PyUnicode_FromUnicode(NULL, 0);
+ result = PyUnicode_FromUnicode(NULL, size - 1);
+ if (!result)
+ return NULL;
+ if (GetComputerNameExW(ComputerNamePhysicalDnsHostname,
+ PyUnicode_AS_UNICODE(result),
+ &size))
+ return result;
+ Py_DECREF(result);
+ }
+ return PyErr_SetExcFromWindowsErr(PyExc_WindowsError, GetLastError());
+ }
+ return PyUnicode_FromUnicode(buf, size);
+#else
char buf[1024];
int res;
Py_BEGIN_ALLOW_THREADS
@@ -3183,7 +3143,8 @@ socket_gethostname(PyObject *self, PyObject *unused)
if (res < 0)
return set_error();
buf[sizeof buf - 1] = '\0';
- return PyString_FromString(buf);
+ return PyUnicode_FromString(buf);
+#endif
}
PyDoc_STRVAR(gethostname_doc,
@@ -3200,12 +3161,16 @@ socket_gethostbyname(PyObject *self, PyObject *args)
{
char *name;
sock_addr_t addrbuf;
+ PyObject *ret = NULL;
- if (!PyArg_ParseTuple(args, "s:gethostbyname", &name))
+ if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name))
return NULL;
if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0)
- return NULL;
- return makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
+ goto finally;
+ ret = makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
+finally:
+ PyMem_Free(name);
+ return ret;
}
PyDoc_STRVAR(gethostbyname_doc,
@@ -3227,11 +3192,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af)
if (h == NULL) {
/* Let's get real error message to return */
-#ifndef RISCOS
set_herror(h_errno);
-#else
- PyErr_SetString(socket_error, "host not found");
-#endif
return NULL;
}
@@ -3269,7 +3230,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af)
if (h->h_aliases) {
for (pch = h->h_aliases; *pch != NULL; pch++) {
int status;
- tmp = PyString_FromString(*pch);
+ tmp = PyUnicode_FromString(*pch);
if (tmp == NULL)
goto err;
@@ -3360,7 +3321,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
struct sockaddr_in addr;
#endif
struct sockaddr *sa;
- PyObject *ret;
+ PyObject *ret = NULL;
#ifdef HAVE_GETHOSTBYNAME_R
struct hostent hp_allocated;
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
@@ -3375,10 +3336,10 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
#endif
#endif /* HAVE_GETHOSTBYNAME_R */
- if (!PyArg_ParseTuple(args, "s:gethostbyname_ex", &name))
+ if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name))
return NULL;
if (setipaddr(name, (struct sockaddr *)&addr, sizeof(addr), AF_INET) < 0)
- return NULL;
+ goto finally;
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_GETHOSTBYNAME_R
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
@@ -3408,6 +3369,8 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
#ifdef USE_GETHOSTBYNAME_LOCK
PyThread_release_lock(netdb_lock);
#endif
+finally:
+ PyMem_Free(name);
return ret;
}
@@ -3432,7 +3395,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
struct sockaddr *sa = (struct sockaddr *)&addr;
char *ip_num;
struct hostent *h;
- PyObject *ret;
+ PyObject *ret = NULL;
#ifdef HAVE_GETHOSTBYNAME_R
struct hostent hp_allocated;
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
@@ -3454,13 +3417,14 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
int al;
int af;
- if (!PyArg_ParseTuple(args, "s:gethostbyaddr", &ip_num))
+ if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num))
return NULL;
af = AF_UNSPEC;
if (setipaddr(ip_num, sa, sizeof(addr), af) < 0)
- return NULL;
+ goto finally;
af = sa->sa_family;
ap = NULL;
+ al = 0;
switch (af) {
case AF_INET:
ap = (char *)&((struct sockaddr_in *)sa)->sin_addr;
@@ -3474,7 +3438,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
#endif
default:
PyErr_SetString(socket_error, "unsupported address family");
- return NULL;
+ goto finally;
}
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_GETHOSTBYNAME_R
@@ -3501,6 +3465,8 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
#ifdef USE_GETHOSTBYNAME_LOCK
PyThread_release_lock(netdb_lock);
#endif
+finally:
+ PyMem_Free(ip_num);
return ret;
}
@@ -3530,7 +3496,7 @@ socket_getservbyname(PyObject *self, PyObject *args)
PyErr_SetString(socket_error, "service/proto not found");
return NULL;
}
- return PyInt_FromLong((long) ntohs(sp->s_port));
+ return PyLong_FromLong((long) ntohs(sp->s_port));
}
PyDoc_STRVAR(getservbyname_doc,
@@ -3567,7 +3533,7 @@ socket_getservbyport(PyObject *self, PyObject *args)
PyErr_SetString(socket_error, "port/proto not found");
return NULL;
}
- return PyString_FromString(sp->s_name);
+ return PyUnicode_FromString(sp->s_name);
}
PyDoc_STRVAR(getservbyport_doc,
@@ -3587,11 +3553,6 @@ socket_getprotobyname(PyObject *self, PyObject *args)
{
char *name;
struct protoent *sp;
-#ifdef __BEOS__
-/* Not available in BeOS yet. - [cjh] */
- PyErr_SetString(socket_error, "getprotobyname not supported");
- return NULL;
-#else
if (!PyArg_ParseTuple(args, "s:getprotobyname", &name))
return NULL;
Py_BEGIN_ALLOW_THREADS
@@ -3601,8 +3562,7 @@ socket_getprotobyname(PyObject *self, PyObject *args)
PyErr_SetString(socket_error, "protocol not found");
return NULL;
}
- return PyInt_FromLong((long) sp->p_proto);
-#endif
+ return PyLong_FromLong((long) sp->p_proto);
}
PyDoc_STRVAR(getprotobyname_doc,
@@ -3611,6 +3571,38 @@ PyDoc_STRVAR(getprotobyname_doc,
Return the protocol number for the named protocol. (Rarely used.)");
+#ifndef NO_DUP
+/* dup() function for socket fds */
+
+static PyObject *
+socket_dup(PyObject *self, PyObject *fdobj)
+{
+ SOCKET_T fd, newfd;
+ PyObject *newfdobj;
+
+
+ fd = PyLong_AsSocket_t(fdobj);
+ if (fd == (SOCKET_T)(-1) && PyErr_Occurred())
+ return NULL;
+
+ newfd = dup_socket(fd);
+ if (newfd == INVALID_SOCKET)
+ return set_error();
+
+ newfdobj = PyLong_FromSocket_t(newfd);
+ if (newfdobj == NULL)
+ SOCKETCLOSE(newfd);
+ return newfdobj;
+}
+
+PyDoc_STRVAR(dup_doc,
+"dup(integer) -> integer\n\
+\n\
+Duplicate an integer socket file descriptor. This is like os.dup(), but for\n\
+sockets; on some platforms os.dup() won't work for socket file descriptors.");
+#endif
+
+
#ifdef HAVE_SOCKETPAIR
/* Create a pair of sockets using the socketpair() function.
Arguments as for socket() except the default family is AF_UNIX if
@@ -3667,39 +3659,6 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET.");
#endif /* HAVE_SOCKETPAIR */
-#ifndef NO_DUP
-/* Create a socket object from a numeric file description.
- Useful e.g. if stdin is a socket.
- Additional arguments as for socket(). */
-
-/*ARGSUSED*/
-static PyObject *
-socket_fromfd(PyObject *self, PyObject *args)
-{
- PySocketSockObject *s;
- SOCKET_T fd;
- int family, type, proto = 0;
- if (!PyArg_ParseTuple(args, "iii|i:fromfd",
- &fd, &family, &type, &proto))
- return NULL;
- /* Dup the fd so it and the socket can be closed independently */
- fd = dup(fd);
- if (fd < 0)
- return set_error();
- s = new_sockobject(fd, family, type, proto);
- return (PyObject *) s;
-}
-
-PyDoc_STRVAR(fromfd_doc,
-"fromfd(fd, family, type[, proto]) -> socket object\n\
-\n\
-Create a socket object from a duplicate of the given\n\
-file descriptor.\n\
-The remaining arguments are the same as for socket().");
-
-#endif /* NO_DUP */
-
-
static PyObject *
socket_ntohs(PyObject *self, PyObject *args)
{
@@ -3714,7 +3673,7 @@ socket_ntohs(PyObject *self, PyObject *args)
return NULL;
}
x2 = (unsigned int)ntohs((unsigned short)x1);
- return PyInt_FromLong(x2);
+ return PyLong_FromLong(x2);
}
PyDoc_STRVAR(ntohs_doc,
@@ -3728,17 +3687,7 @@ socket_ntohl(PyObject *self, PyObject *arg)
{
unsigned long x;
- if (PyInt_Check(arg)) {
- x = PyInt_AS_LONG(arg);
- if (x == (unsigned long) -1 && PyErr_Occurred())
- return NULL;
- if ((long)x < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative number to unsigned long");
- return NULL;
- }
- }
- else if (PyLong_Check(arg)) {
+ if (PyLong_Check(arg)) {
x = PyLong_AsUnsignedLong(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
@@ -3783,7 +3732,7 @@ socket_htons(PyObject *self, PyObject *args)
return NULL;
}
x2 = (unsigned int)htons((unsigned short)x1);
- return PyInt_FromLong(x2);
+ return PyLong_FromLong(x2);
}
PyDoc_STRVAR(htons_doc,
@@ -3797,17 +3746,7 @@ socket_htonl(PyObject *self, PyObject *arg)
{
unsigned long x;
- if (PyInt_Check(arg)) {
- x = PyInt_AS_LONG(arg);
- if (x == (unsigned long) -1 && PyErr_Occurred())
- return NULL;
- if ((long)x < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "can't convert negative number to unsigned long");
- return NULL;
- }
- }
- else if (PyLong_Check(arg)) {
+ if (PyLong_Check(arg)) {
x = PyLong_AsUnsignedLong(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
@@ -3838,7 +3777,7 @@ Convert a 32-bit integer from host to network byte order.");
/* socket.inet_aton() and socket.inet_ntoa() functions. */
PyDoc_STRVAR(inet_aton_doc,
-"inet_aton(string) -> packed 32-bit IP representation\n\
+"inet_aton(string) -> bytes giving packed 32-bit IP representation\n\
\n\
Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\
binary format used in low-level network functions.");
@@ -3872,7 +3811,7 @@ socket_inet_aton(PyObject *self, PyObject *args)
if (inet_aton != NULL) {
#endif
if (inet_aton(ip_addr, &buf))
- return PyString_FromStringAndSize((char *)(&buf),
+ return PyBytes_FromStringAndSize((char *)(&buf),
sizeof(buf));
PyErr_SetString(socket_error,
@@ -3901,7 +3840,7 @@ socket_inet_aton(PyObject *self, PyObject *args)
return NULL;
}
}
- return PyString_FromStringAndSize((char *) &packed_addr,
+ return PyBytes_FromStringAndSize((char *) &packed_addr,
sizeof(packed_addr));
#ifdef USE_INET_ATON_WEAKLINK
@@ -3923,7 +3862,7 @@ socket_inet_ntoa(PyObject *self, PyObject *args)
int addr_len;
struct in_addr packed_addr;
- if (!PyArg_ParseTuple(args, "s#:inet_ntoa", &packed_str, &addr_len)) {
+ if (!PyArg_ParseTuple(args, "y#:inet_ntoa", &packed_str, &addr_len)) {
return NULL;
}
@@ -3935,7 +3874,7 @@ socket_inet_ntoa(PyObject *self, PyObject *args)
memcpy(&packed_addr, packed_str, addr_len);
- return PyString_FromString(inet_ntoa(packed_addr));
+ return PyUnicode_FromString(inet_ntoa(packed_addr));
}
#ifdef HAVE_INET_PTON
@@ -3978,12 +3917,12 @@ socket_inet_pton(PyObject *self, PyObject *args)
"illegal IP address string passed to inet_pton");
return NULL;
} else if (af == AF_INET) {
- return PyString_FromStringAndSize(packed,
- sizeof(struct in_addr));
+ return PyBytes_FromStringAndSize(packed,
+ sizeof(struct in_addr));
#ifdef ENABLE_IPV6
} else if (af == AF_INET6) {
- return PyString_FromStringAndSize(packed,
- sizeof(struct in6_addr));
+ return PyBytes_FromStringAndSize(packed,
+ sizeof(struct in6_addr));
#endif
} else {
PyErr_SetString(socket_error, "unknown address family");
@@ -4009,10 +3948,10 @@ socket_inet_ntop(PyObject *self, PyObject *args)
char ip[INET_ADDRSTRLEN + 1];
#endif
- /* Guarantee NUL-termination for PyString_FromString() below */
+ /* Guarantee NUL-termination for PyUnicode_FromString() below */
memset((void *) &ip[0], '\0', sizeof(ip));
- if (!PyArg_ParseTuple(args, "is#:inet_ntop", &af, &packed, &len)) {
+ if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) {
return NULL;
}
@@ -4041,7 +3980,7 @@ socket_inet_ntop(PyObject *self, PyObject *args)
PyErr_SetFromErrno(socket_error);
return NULL;
} else {
- return PyString_FromString(retval);
+ return PyUnicode_FromString(retval);
}
/* NOTREACHED */
@@ -4055,8 +3994,10 @@ socket_inet_ntop(PyObject *self, PyObject *args)
/*ARGSUSED*/
static PyObject *
-socket_getaddrinfo(PyObject *self, PyObject *args)
+socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs)
{
+ static char* kwnames[] = {"host", "port", "family", "type", "proto",
+ "flags", 0};
struct addrinfo hints, *res;
struct addrinfo *res0 = NULL;
PyObject *hobj = NULL;
@@ -4066,13 +4007,12 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
int family, socktype, protocol, flags;
int error;
PyObject *all = (PyObject *)NULL;
- PyObject *single = (PyObject *)NULL;
PyObject *idna = NULL;
family = socktype = protocol = flags = 0;
family = AF_UNSPEC;
- if (!PyArg_ParseTuple(args, "OO|iiii:getaddrinfo",
- &hobj, &pobj, &family, &socktype,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo",
+ kwnames, &hobj, &pobj, &family, &socktype,
&protocol, &flags)) {
return NULL;
}
@@ -4082,27 +4022,31 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
idna = PyObject_CallMethod(hobj, "encode", "s", "idna");
if (!idna)
return NULL;
- hptr = PyString_AsString(idna);
- } else if (PyString_Check(hobj)) {
- hptr = PyString_AsString(hobj);
+ assert(PyBytes_Check(idna));
+ hptr = PyBytes_AS_STRING(idna);
+ } else if (PyBytes_Check(hobj)) {
+ hptr = PyBytes_AsString(hobj);
} else {
PyErr_SetString(PyExc_TypeError,
"getaddrinfo() argument 1 must be string or None");
return NULL;
}
- if (PyInt_Check(pobj) || PyLong_Check(pobj)) {
+ if (PyLong_CheckExact(pobj)) {
long value = PyLong_AsLong(pobj);
if (value == -1 && PyErr_Occurred())
- return NULL;
+ goto err;
PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", value);
pptr = pbuf;
- } else if (PyString_Check(pobj)) {
- pptr = PyString_AsString(pobj);
+ } else if (PyUnicode_Check(pobj)) {
+ pptr = _PyUnicode_AsString(pobj);
+ if (pptr == NULL)
+ goto err;
+ } else if (PyBytes_Check(pobj)) {
+ pptr = PyBytes_AS_STRING(pobj);
} else if (pobj == Py_None) {
pptr = (char *)NULL;
} else {
- PyErr_SetString(socket_error,
- "getaddrinfo() argument 2 must be integer or string");
+ PyErr_SetString(socket_error, "Int or String expected");
goto err;
}
memset(&hints, 0, sizeof(hints));
@@ -4123,6 +4067,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
if ((all = PyList_New(0)) == NULL)
goto err;
for (res = res0; res; res = res->ai_next) {
+ PyObject *single;
PyObject *addr =
makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol);
if (addr == NULL)
@@ -4144,7 +4089,6 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
freeaddrinfo(res0);
return all;
err:
- Py_XDECREF(single);
Py_XDECREF(all);
Py_XDECREF(idna);
if (res0)
@@ -4194,6 +4138,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; /* make numeric port happy */
+ hints.ai_flags = AI_NUMERICHOST; /* don't do any name resolution */
Py_BEGIN_ALLOW_THREADS
ACQUIRE_GETADDRINFO_LOCK
error = getaddrinfo(hostp, pbuf, &hints, &res);
@@ -4229,7 +4174,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
}
#endif
}
- error = getnameinfo(res->ai_addr, res->ai_addrlen,
+ error = getnameinfo(res->ai_addr, (socklen_t) res->ai_addrlen,
hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags);
if (error) {
set_gaierror(error);
@@ -4318,8 +4263,8 @@ static PyMethodDef socket_methods[] = {
{"getprotobyname", socket_getprotobyname,
METH_VARARGS, getprotobyname_doc},
#ifndef NO_DUP
- {"fromfd", socket_fromfd,
- METH_VARARGS, fromfd_doc},
+ {"dup", socket_dup,
+ METH_O, dup_doc},
#endif
#ifdef HAVE_SOCKETPAIR
{"socketpair", socket_socketpair,
@@ -4343,8 +4288,8 @@ static PyMethodDef socket_methods[] = {
{"inet_ntop", socket_inet_ntop,
METH_VARARGS, inet_ntop_doc},
#endif
- {"getaddrinfo", socket_getaddrinfo,
- METH_VARARGS, getaddrinfo_doc},
+ {"getaddrinfo", (PyCFunction)socket_getaddrinfo,
+ METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc},
{"getnameinfo", socket_getnameinfo,
METH_VARARGS, getnameinfo_doc},
{"getdefaulttimeout", (PyCFunction)socket_getdefaulttimeout,
@@ -4355,24 +4300,6 @@ static PyMethodDef socket_methods[] = {
};
-#ifdef RISCOS
-#define OS_INIT_DEFINED
-
-static int
-os_init(void)
-{
- _kernel_swi_regs r;
-
- r.r[0] = 0;
- _kernel_swi(0x43380, &r, &r);
- taskwindow = r.r[0];
-
- return 1;
-}
-
-#endif /* RISCOS */
-
-
#ifdef MS_WINDOWS
#define OS_INIT_DEFINED
@@ -4389,7 +4316,6 @@ os_init(void)
{
WSADATA WSAData;
int ret;
- char buf[100];
ret = WSAStartup(0x0101, &WSAData);
switch (ret) {
case 0: /* No error */
@@ -4406,9 +4332,7 @@ os_init(void)
"WSAStartup failed: requested version not supported");
break;
default:
- PyOS_snprintf(buf, sizeof(buf),
- "WSAStartup failed: error code %d", ret);
- PyErr_SetString(PyExc_ImportError, buf);
+ PyErr_Format(PyExc_ImportError, "WSAStartup failed: error code %d", ret);
break;
}
return 0; /* Failure */
@@ -4426,16 +4350,13 @@ static int
os_init(void)
{
#ifndef PYCC_GCC
- char reason[64];
int rc = sock_init();
if (rc == 0) {
return 1; /* Success */
}
- PyOS_snprintf(reason, sizeof(reason),
- "OS/2 TCP/IP Error# %d", sock_errno());
- PyErr_SetString(PyExc_ImportError, reason);
+ PyErr_Format(PyExc_ImportError, "OS/2 TCP/IP Error# %d", sock_errno());
return 0; /* Failure */
#else
@@ -4462,6 +4383,7 @@ static
PySocketModule_APIObject PySocketModuleAPI =
{
&sock_type,
+ NULL,
NULL
};
@@ -4469,14 +4391,11 @@ PySocketModule_APIObject PySocketModuleAPI =
/* Initialize the _socket module.
This module is actually called "_socket", and there's a wrapper
- "socket.py" which implements some additional functionality. On some
- platforms (e.g. Windows and OS/2), socket.py also implements a
- wrapper for the socket type that provides missing functionality such
- as makefile(), dup() and fromfd(). The import of "_socket" may fail
- with an ImportError exception if os-specific initialization fails.
- On Windows, this does WINSOCK initialization. When WINSOCK is
- initialized successfully, a call to WSACleanup() is scheduled to be
- made at exit time.
+ "socket.py" which implements some additional functionality.
+ The import of "_socket" may fail with an ImportError exception if
+ os-specific initialization fails. On Windows, this does WINSOCK
+ initialization. When WINSOCK is initialized successfully, a call to
+ WSACleanup() is scheduled to be made at exit time.
*/
PyDoc_STRVAR(socket_doc,
@@ -4484,54 +4403,65 @@ PyDoc_STRVAR(socket_doc,
\n\
See the socket module for documentation.");
+static struct PyModuleDef socketmodule = {
+ PyModuleDef_HEAD_INIT,
+ PySocket_MODULE_NAME,
+ socket_doc,
+ -1,
+ socket_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
PyMODINIT_FUNC
-init_socket(void)
+PyInit__socket(void)
{
PyObject *m, *has_ipv6;
if (!os_init())
- return;
+ return NULL;
Py_TYPE(&sock_type) = &PyType_Type;
- m = Py_InitModule3(PySocket_MODULE_NAME,
- socket_methods,
- socket_doc);
+ m = PyModule_Create(&socketmodule);
if (m == NULL)
- return;
+ return NULL;
socket_error = PyErr_NewException("socket.error",
PyExc_IOError, NULL);
if (socket_error == NULL)
- return;
+ return NULL;
PySocketModuleAPI.error = socket_error;
Py_INCREF(socket_error);
PyModule_AddObject(m, "error", socket_error);
socket_herror = PyErr_NewException("socket.herror",
socket_error, NULL);
if (socket_herror == NULL)
- return;
+ return NULL;
Py_INCREF(socket_herror);
PyModule_AddObject(m, "herror", socket_herror);
socket_gaierror = PyErr_NewException("socket.gaierror", socket_error,
NULL);
if (socket_gaierror == NULL)
- return;
+ return NULL;
Py_INCREF(socket_gaierror);
PyModule_AddObject(m, "gaierror", socket_gaierror);
socket_timeout = PyErr_NewException("socket.timeout",
socket_error, NULL);
if (socket_timeout == NULL)
- return;
+ return NULL;
+ PySocketModuleAPI.timeout_error = socket_timeout;
Py_INCREF(socket_timeout);
PyModule_AddObject(m, "timeout", socket_timeout);
Py_INCREF((PyObject *)&sock_type);
if (PyModule_AddObject(m, "SocketType",
(PyObject *)&sock_type) != 0)
- return;
+ return NULL;
Py_INCREF((PyObject *)&sock_type);
if (PyModule_AddObject(m, "socket",
(PyObject *)&sock_type) != 0)
- return;
+ return NULL;
#ifdef ENABLE_IPV6
has_ipv6 = Py_True;
@@ -4545,7 +4475,7 @@ init_socket(void)
if (PyModule_AddObject(m, PySocket_CAPI_NAME,
PyCapsule_New(&PySocketModuleAPI, PySocket_CAPSULE_NAME, NULL)
) != 0)
- return;
+ return NULL;
/* Address families (we only support AF_INET and AF_UNIX) */
#ifdef AF_UNSPEC
@@ -4779,13 +4709,17 @@ init_socket(void)
/* Socket types */
PyModule_AddIntConstant(m, "SOCK_STREAM", SOCK_STREAM);
PyModule_AddIntConstant(m, "SOCK_DGRAM", SOCK_DGRAM);
-#ifndef __BEOS__
/* We have incomplete socket support. */
PyModule_AddIntConstant(m, "SOCK_RAW", SOCK_RAW);
PyModule_AddIntConstant(m, "SOCK_SEQPACKET", SOCK_SEQPACKET);
#if defined(SOCK_RDM)
PyModule_AddIntConstant(m, "SOCK_RDM", SOCK_RDM);
#endif
+#ifdef SOCK_CLOEXEC
+ PyModule_AddIntConstant(m, "SOCK_CLOEXEC", SOCK_CLOEXEC);
+#endif
+#ifdef SOCK_NONBLOCK
+ PyModule_AddIntConstant(m, "SOCK_NONBLOCK", SOCK_NONBLOCK);
#endif
#ifdef SO_DEBUG
@@ -4846,7 +4780,7 @@ init_socket(void)
#ifdef SO_TYPE
PyModule_AddIntConstant(m, "SO_TYPE", SO_TYPE);
#endif
-#ifdef SO_SETFIB
+#ifdef SO_SETFIB
PyModule_AddIntConstant(m, "SO_SETFIB", SO_SETFIB);
#endif
@@ -5402,7 +5336,7 @@ init_socket(void)
PyObject *tmp;
tmp = PyLong_FromUnsignedLong(codes[i]);
if (tmp == NULL)
- return;
+ return NULL;
PyModule_AddObject(m, names[i], tmp);
}
}
@@ -5421,6 +5355,7 @@ init_socket(void)
#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
netdb_lock = PyThread_allocate_lock();
#endif
+ return m;
}