diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2010-04-09 21:00:36 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2010-04-09 21:00:36 (GMT) |
commit | 9c6cd56e9177cda47f3b836159696f6471408b47 (patch) | |
tree | f2747e81ed7b275041d14da349c7b16cc6522bf8 /Modules | |
parent | 92719c546ff24c8b133e09bc0ded108374b2eaec (diff) | |
download | cpython-9c6cd56e9177cda47f3b836159696f6471408b47.zip cpython-9c6cd56e9177cda47f3b836159696f6471408b47.tar.gz cpython-9c6cd56e9177cda47f3b836159696f6471408b47.tar.bz2 |
Temporarily commit fix to issue #8108, to check for buildbot response
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ssl.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 986ec46..3047d97 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1347,7 +1347,7 @@ Read up to len bytes from the SSL socket."); static PyObject *PySSL_SSLshutdown(PySSLObject *self) { - int err; + int err, ssl_err, sockstate; /* Guard against closed socket */ if (self->Socket->sock_fd < 0) { @@ -1356,13 +1356,42 @@ static PyObject *PySSL_SSLshutdown(PySSLObject *self) return NULL; } - PySSL_BEGIN_ALLOW_THREADS - err = SSL_shutdown(self->ssl); - if (err == 0) { - /* we need to call it again to finish the shutdown */ + while (1) { + PySSL_BEGIN_ALLOW_THREADS err = SSL_shutdown(self->ssl); + if (err == 0) { + /* we need to call it again to finish the shutdown */ + err = SSL_shutdown(self->ssl); + } + PySSL_END_ALLOW_THREADS + if (err >= 0) + break; + /* Possibly retry shutdown until timeout or failure */ + ssl_err = SSL_get_error(self->ssl, err); + if (ssl_err == SSL_ERROR_WANT_READ) + sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); + else if (ssl_err == SSL_ERROR_WANT_WRITE) + sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); + else + break; + if (sockstate == SOCKET_HAS_TIMED_OUT) { + if (ssl_err == SSL_ERROR_WANT_READ) + PyErr_SetString(PySSLErrorObject, + "The read operation timed out"); + else + PyErr_SetString(PySSLErrorObject, + "The write operation timed out"); + return NULL; + } + else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { + PyErr_SetString(PySSLErrorObject, + "Underlying socket too large for select()."); + return NULL; + } + else if (sockstate != SOCKET_OPERATION_OK) + /* Retain the SSL error code */ + break; } - PySSL_END_ALLOW_THREADS if (err < 0) return PySSL_SetError(self, err, __FILE__, __LINE__); |