[3.13] gh-100218: correctly set errno when socket.if_{nametoindex,indextoname} raise OSError (GH-140905) (#141285)

Previously, socket.if_nametoindex() and socket.if_indextoname() could raise
an `OSError` with a `None` errno. Now, the errno from libc is propagated.

(cherry picked from commit 3ce2d57b2f)
This commit is contained in:
Bénédikt Tran 2025-11-09 14:31:49 +01:00 committed by GitHub
parent 052a53982a
commit 873f0d023c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 14 additions and 4 deletions

View file

@ -1167,7 +1167,10 @@ def testInterfaceNameIndex(self):
@unittest.skipUnless(hasattr(socket, 'if_indextoname'),
'socket.if_indextoname() not available.')
def testInvalidInterfaceIndexToName(self):
self.assertRaises(OSError, socket.if_indextoname, 0)
with self.assertRaises(OSError) as cm:
socket.if_indextoname(0)
self.assertIsNotNone(cm.exception.errno)
self.assertRaises(OverflowError, socket.if_indextoname, -1)
self.assertRaises(OverflowError, socket.if_indextoname, 2**1000)
self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF')
@ -1186,8 +1189,11 @@ def testInvalidInterfaceIndexToName(self):
@unittest.skipUnless(hasattr(socket, 'if_nametoindex'),
'socket.if_nametoindex() not available.')
def testInvalidInterfaceNameToIndex(self):
with self.assertRaises(OSError) as cm:
socket.if_nametoindex("_DEADBEEF")
self.assertIsNotNone(cm.exception.errno)
self.assertRaises(TypeError, socket.if_nametoindex, 0)
self.assertRaises(OSError, socket.if_nametoindex, '_DEADBEEF')
@unittest.skipUnless(hasattr(sys, 'getrefcount'),
'test needs sys.getrefcount()')

View file

@ -0,0 +1,3 @@
Correctly set :attr:`~OSError.errno` when :func:`socket.if_nametoindex` or
:func:`socket.if_indextoname` raise an :exc:`OSError`. Patch by Bénédikt
Tran.

View file

@ -7114,10 +7114,10 @@ _socket_socket_if_nametoindex_impl(PySocketSockObject *self, PyObject *oname)
unsigned long index;
#endif
errno = ENODEV; // in case 'if_nametoindex' does not set errno
index = if_nametoindex(PyBytes_AS_STRING(oname));
if (index == 0) {
/* if_nametoindex() doesn't set errno */
PyErr_SetString(PyExc_OSError, "no interface with this name");
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
@ -7144,6 +7144,7 @@ socket_if_indextoname(PyObject *self, PyObject *arg)
return NULL;
}
errno = ENXIO; // in case 'if_indextoname' does not set errno
char name[IF_NAMESIZE + 1];
if (if_indextoname(index, name) == NULL) {
PyErr_SetFromErrno(PyExc_OSError);