--- Modules/socketmodule.c 2006-02-20 04:42:37.000000000 -0500 +++ Modules/socketmodule.c 2006-06-27 11:42:22.000000000 -0400 @@ -644,7 +644,7 @@ internal_setblocking(PySocketSockObject The argument writing indicates the direction. This does not raise an exception; we'll let our caller do that after they've reacquired the interpreter lock. - Returns 1 on timeout, 0 otherwise. */ + Returns 1 on timeout, -1 on error, 0 otherwise. */ static int internal_select(PySocketSockObject *s, int writing) { @@ -671,6 +671,9 @@ internal_select(PySocketSockObject *s, i n = select(s->sock_fd+1, NULL, &fds, NULL, &tv); else n = select(s->sock_fd+1, &fds, NULL, NULL, &tv); + + if (n < 0) + return -1; if (n == 0) return 1; return 0; @@ -1389,7 +1392,7 @@ sock_accept(PySocketSockObject *s) &addrlen); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -1758,9 +1761,15 @@ internal_connect(PySocketSockObject *s, if (s->sock_timeout > 0.0) { if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { timeout = internal_select(s, 1); - res = connect(s->sock_fd, addr, addrlen); - if (res < 0 && errno == EISCONN) - res = 0; + if (timeout == 0) { + res = connect(s->sock_fd, addr, addrlen); + if (res < 0 && errno == EISCONN) + res = 0; + } + else if (timeout == -1) + res = errno; /* had error */ + else + res = EWOULDBLOCK; /* timed out */ } } @@ -1790,7 +1799,7 @@ sock_connect(PySocketSockObject *s, PyOb res = internal_connect(s, addr, addrlen, &timeout); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -1824,6 +1833,13 @@ sock_connect_ex(PySocketSockObject *s, P res = internal_connect(s, addr, addrlen, &timeout); Py_END_ALLOW_THREADS + /* Signals are not errors (though they may raise exceptions). Adapted + from PyErr_SetFromErrnoWithFilenameObject(). */ +#ifdef EINTR + if (res == EINTR && PyErr_CheckSignals()) + return NULL; +#endif + return PyInt_FromLong((long) res); } @@ -2039,7 +2055,7 @@ The mode and buffersize arguments are as static PyObject * sock_recv(PySocketSockObject *s, PyObject *args) { - int len, n = 0, flags = 0, timeout; + int len, n = -1, flags = 0, timeout; PyObject *buf; #ifdef __VMS int read_length; @@ -2069,7 +2085,7 @@ sock_recv(PySocketSockObject *s, PyObjec n = recv(s->sock_fd, PyString_AS_STRING(buf), len, flags); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { Py_DECREF(buf); PyErr_SetString(socket_timeout, "timed out"); return NULL; @@ -2096,11 +2112,12 @@ sock_recv(PySocketSockObject *s, PyObjec Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 0); + n = -1; if (!timeout) n = recv(s->sock_fd, read_buf, segment, flags); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { Py_DECREF(buf); PyErr_SetString(socket_timeout, "timed out"); return NULL; @@ -2143,7 +2160,7 @@ sock_recvfrom(PySocketSockObject *s, PyO PyObject *buf = NULL; PyObject *addr = NULL; PyObject *ret = NULL; - int len, n = 0, flags = 0, timeout; + int len, n = -1, flags = 0, timeout; socklen_t addrlen; if (!PyArg_ParseTuple(args, "i|i:recvfrom", &len, &flags)) @@ -2175,7 +2192,7 @@ sock_recvfrom(PySocketSockObject *s, PyO ); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { Py_DECREF(buf); PyErr_SetString(socket_timeout, "timed out"); return NULL; @@ -2211,7 +2228,7 @@ static PyObject * sock_send(PySocketSockObject *s, PyObject *args) { char *buf; - int len, n = 0, flags = 0, timeout; + int len, n = -1, flags = 0, timeout; #ifdef __VMS int send_length; #endif @@ -2229,7 +2246,7 @@ sock_send(PySocketSockObject *s, PyObjec n = send(s->sock_fd, buf, len, flags); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -2251,10 +2268,11 @@ sock_send(PySocketSockObject *s, PyObjec } Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 1); + n = -1; if (!timeout) n = send(s->sock_fd, buf, segment, flags); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -2282,7 +2300,7 @@ static PyObject * sock_sendall(PySocketSockObject *s, PyObject *args) { char *buf; - int len, n = 0, flags = 0, timeout; + int len, n = -1, flags = 0, timeout; if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags)) return NULL; @@ -2293,6 +2311,7 @@ sock_sendall(PySocketSockObject *s, PyOb Py_BEGIN_ALLOW_THREADS do { timeout = internal_select(s, 1); + n = -1; if (timeout) break; n = send(s->sock_fd, buf, len, flags); @@ -2303,7 +2322,7 @@ sock_sendall(PySocketSockObject *s, PyOb } while (len > 0); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -2331,7 +2350,7 @@ sock_sendto(PySocketSockObject *s, PyObj PyObject *addro; char *buf; struct sockaddr *addr; - int addrlen, len, n = 0, flags, timeout; + int addrlen, len, n = -1, flags, timeout; flags = 0; if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) { @@ -2353,7 +2372,7 @@ sock_sendto(PySocketSockObject *s, PyObj n = sendto(s->sock_fd, buf, len, flags, addr, addrlen); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; }