]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-100218: correctly set `errno` when `socket.if_{nametoindex,indextoname...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 9 Nov 2025 13:11:43 +0000 (14:11 +0100)
committerGitHub <noreply@github.com>
Sun, 9 Nov 2025 13:11:43 +0000 (13:11 +0000)
gh-100218: correctly set `errno` when `socket.if_{nametoindex,indextoname}` raise `OSError` (GH-140905)

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 3ce2d57b2f02030353af314d89c5f6215d2f5c96)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Lib/test/test_socket.py
Misc/NEWS.d/next/Library/2025-11-02-11-46-00.gh-issue-100218.9Ezfdq.rst [new file with mode: 0644]
Modules/socketmodule.c

index cfb9619341b3240882adfada7c5edeb8a0060527..e66160c5236261e1f2bfa54159ef0601577cee1a 100644 (file)
@@ -1174,7 +1174,10 @@ class GeneralModuleTests(unittest.TestCase):
                          'socket.if_indextoname() not available.')
     @support.skip_android_selinux('if_indextoname')
     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(ValueError, socket.if_indextoname, -1)
         self.assertRaises(OverflowError, socket.if_indextoname, 2**1000)
         self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF')
@@ -1194,8 +1197,11 @@ class GeneralModuleTests(unittest.TestCase):
                          'socket.if_nametoindex() not available.')
     @support.skip_android_selinux('if_nametoindex')
     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()')
diff --git a/Misc/NEWS.d/next/Library/2025-11-02-11-46-00.gh-issue-100218.9Ezfdq.rst b/Misc/NEWS.d/next/Library/2025-11-02-11-46-00.gh-issue-100218.9Ezfdq.rst
new file mode 100644 (file)
index 0000000..2f7500d
--- /dev/null
@@ -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.
index c90b693dd2d62b39a66dfe2e72454fea8fc4e46c..1fbd6eb9294cfaf87dd9e4a5402f116991dea877 100644 (file)
@@ -7277,10 +7277,10 @@ _socket_if_nametoindex_impl(PyObject *module, 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;
     }
 
@@ -7300,6 +7300,7 @@ static PyObject *
 _socket_if_indextoname_impl(PyObject *module, NET_IFINDEX index)
 /*[clinic end generated code: output=e48bc324993052e0 input=c93f753d0cf6d7d1]*/
 {
+    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);