From 6071359de177ba2db621ff698fb4e7c4e1287294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Fran=C3=A7ois=20Natali?= Date: Fri, 20 May 2011 16:55:06 +0200 Subject: Issue #1746656: make if_nameindex(), if_indextoname() and if_nametoindex() accept and return str instead of bytes arrays. Add some more tests. --- Lib/test/test_socket.py | 20 ++++++++++++++-- Modules/socketmodule.c | 61 ++++++++++++++++++++++++------------------------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index ffa2587..a449f5b 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -377,10 +377,26 @@ class GeneralModuleTests(unittest.TestCase): def testInterfaceNameIndex(self): interfaces = socket.if_nameindex() for index, name in interfaces: + self.assertIsInstance(index, int) + self.assertIsInstance(name, str) # interface indices are non-zero integers self.assertGreater(index, 0) - self.assertEqual(index, socket.if_nametoindex(name)) - self.assertEqual(name, socket.if_indextoname(index)) + _index = socket.if_nametoindex(name) + self.assertIsInstance(_index, int) + self.assertEqual(index, _index) + _name = socket.if_indextoname(index) + self.assertIsInstance(_name, str) + self.assertEqual(name, _name) + + @unittest.skipUnless(hasattr(socket, 'if_nameindex'), + 'socket.if_nameindex() not available.') + def testInvalidInterfaceNameIndex(self): + # test nonexistent interface index/name + self.assertRaises(socket.error, socket.if_indextoname, 0) + self.assertRaises(socket.error, socket.if_nametoindex, '_DEADBEEF') + # test with invalid values + self.assertRaises(TypeError, socket.if_nametoindex, 0) + self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF') def testRefCountGetNameInfo(self): # Testing reference count for getnameinfo diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index d3f65aa..8107b98 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -4280,19 +4280,19 @@ Set the default timeout in floating seconds for new socket objects.\n\ A value of None indicates that new socket objects have no timeout.\n\ When the socket module is first imported, the default is None."); - #ifdef HAVE_IF_NAMEINDEX /* Python API for getting interface indices and names */ static PyObject * socket_if_nameindex(PyObject *self, PyObject *arg) { - int i = 0; PyObject *list; - struct if_nameindex *ni = if_nameindex(); - + int i; + struct if_nameindex *ni; + + ni = if_nameindex(); if (ni == NULL) { - PyErr_SetString(socket_error, "if_nameindex() returned NULL."); + PyErr_SetFromErrno(socket_error); return NULL; } @@ -4302,26 +4302,21 @@ socket_if_nameindex(PyObject *self, PyObject *arg) return NULL; } - while (ni[i].if_index != 0 && i < INT_MAX) { - PyObject *ni_tuple = Py_BuildValue( - "Iy", ni[i].if_index, ni[i].if_name); + for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) { + PyObject *ni_tuple = Py_BuildValue("IO&", + ni[i].if_index, PyUnicode_DecodeFSDefault, ni[i].if_name); if (ni_tuple == NULL || PyList_Append(list, ni_tuple) == -1) { Py_XDECREF(ni_tuple); - goto error; + Py_DECREF(list); + if_freenameindex(ni); + return NULL; } Py_DECREF(ni_tuple); - - ++i; } if_freenameindex(ni); return list; - -error: - Py_DECREF(list); - if_freenameindex(ni); - return NULL; } PyDoc_STRVAR(if_nameindex_doc, @@ -4329,18 +4324,20 @@ PyDoc_STRVAR(if_nameindex_doc, \n\ Returns a list of network interface information (index, name) tuples."); - -PyObject* -socket_if_nametoindex(PyObject *self, PyObject *arg) +static PyObject * +socket_if_nametoindex(PyObject *self, PyObject *args) { - char* ifname = PyBytes_AsString(arg); + PyObject *oname; unsigned long index; - if (ifname == NULL) + if (!PyArg_ParseTuple(args, "O&:if_nametoindex", + PyUnicode_FSConverter, &oname)) return NULL; - index = if_nametoindex(ifname); + index = if_nametoindex(PyBytes_AS_STRING(oname)); + Py_DECREF(oname); if (index == 0) { + /* if_nametoindex() doesn't set errno */ PyErr_SetString(socket_error, "no interface with this name"); return NULL; } @@ -4353,20 +4350,22 @@ PyDoc_STRVAR(if_nametoindex_doc, \n\ Returns the interface index corresponding to the interface name if_name."); - -PyObject* +static PyObject * socket_if_indextoname(PyObject *self, PyObject *arg) { - unsigned long index = PyLong_AsUnsignedLongMask(arg); - char name[IF_NAMESIZE + 1]; /* or use IFNAMSIZ ?*/ - char *ret = if_indextoname(index, &name[0]); + unsigned long index; + char name[IF_NAMESIZE + 1]; + + index = PyLong_AsUnsignedLong(arg); + if (index == (unsigned long) -1) + return NULL; - if (ret == NULL) { - PyErr_SetString(socket_error, "no interface with this index"); + if (if_indextoname(index, name) == NULL) { + PyErr_SetFromErrno(socket_error); return NULL; } - return PyBytes_FromString(name); + return PyUnicode_DecodeFSDefault(name); } PyDoc_STRVAR(if_indextoname_doc, @@ -4436,7 +4435,7 @@ static PyMethodDef socket_methods[] = { {"if_nameindex", socket_if_nameindex, METH_NOARGS, if_nameindex_doc}, {"if_nametoindex", socket_if_nametoindex, - METH_O, if_nametoindex_doc}, + METH_VARARGS, if_nametoindex_doc}, {"if_indextoname", socket_if_indextoname, METH_O, if_indextoname_doc}, #endif -- cgit v0.12