diff options
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 995 |
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; } |