Issue #26685: Raise OSError if closing a socket fails

This commit is contained in:
Martin Panter 2016-04-11 00:38:12 +00:00
parent f01e408c16
commit 50ab1a3694
6 changed files with 26 additions and 2 deletions

View File

@ -868,6 +868,10 @@ to sockets.
it is recommended to :meth:`close` them explicitly, or to use a it is recommended to :meth:`close` them explicitly, or to use a
:keyword:`with` statement around them. :keyword:`with` statement around them.
.. versionchanged:: 3.6
:exc:`OSError` is now raised if an error occurs when the underlying
:c:func:`close` call is made.
.. note:: .. note::
:meth:`close()` releases the resource associated with a connection but :meth:`close()` releases the resource associated with a connection but

View File

@ -514,6 +514,10 @@ Changes in the Python API
* :func:`spwd.getspnam` now raises a :exc:`PermissionError` instead of * :func:`spwd.getspnam` now raises a :exc:`PermissionError` instead of
:exc:`KeyError` if the user doesn't have privileges. :exc:`KeyError` if the user doesn't have privileges.
* The :meth:`socket.socket.close` method now raises an exception if
an error (e.g. EBADF) was reported by the underlying system call.
See :issue:`26685`.
Changes in the C API Changes in the C API
-------------------- --------------------

View File

@ -277,7 +277,6 @@ class SmallPtyTests(unittest.TestCase):
socketpair = self._socketpair() socketpair = self._socketpair()
masters = [s.fileno() for s in socketpair] masters = [s.fileno() for s in socketpair]
os.close(masters[1])
socketpair[1].close() socketpair[1].close()
os.close(write_to_stdin_fd) os.close(write_to_stdin_fd)

View File

@ -1161,6 +1161,17 @@ class GeneralModuleTests(unittest.TestCase):
sock.close() sock.close()
self.assertRaises(OSError, sock.send, b"spam") self.assertRaises(OSError, sock.send, b"spam")
def testCloseException(self):
sock = socket.socket()
socket.socket(fileno=sock.fileno()).close()
try:
sock.close()
except OSError as err:
# Winsock apparently raises ENOTSOCK
self.assertIn(err.errno, (errno.EBADF, errno.ENOTSOCK))
else:
self.fail("close() should raise EBADF/ENOTSOCK")
def testNewAttributes(self): def testNewAttributes(self):
# testing .family, .type and .protocol # testing .family, .type and .protocol

View File

@ -240,6 +240,8 @@ Core and Builtins
Library Library
------- -------
- Issue #26685: Raise OSError if closing a socket fails.
- Issue #16329: Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'. - Issue #16329: Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'.
- Issue #13952: Add .csv to mimetypes.types_map. Patch by Geoff Wilson. - Issue #13952: Add .csv to mimetypes.types_map. Patch by Geoff Wilson.

View File

@ -2576,6 +2576,7 @@ static PyObject *
sock_close(PySocketSockObject *s) sock_close(PySocketSockObject *s)
{ {
SOCKET_T fd; SOCKET_T fd;
int res;
fd = s->sock_fd; fd = s->sock_fd;
if (fd != -1) { if (fd != -1) {
@ -2586,8 +2587,11 @@ sock_close(PySocketSockObject *s)
http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
for more details. */ for more details. */
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
(void) SOCKETCLOSE(fd); res = SOCKETCLOSE(fd);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) {
return s->errorhandler();
}
} }
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;