diff options
author | Kristján Valur Jónsson <kristjan@ccpgames.com> | 2009-09-25 15:19:51 +0000 |
---|---|---|
committer | Kristján Valur Jónsson <kristjan@ccpgames.com> | 2009-09-25 15:19:51 +0000 |
commit | 2fcd03bb77fbd3d0b186c15b46de47cf0422ba68 (patch) | |
tree | 77b598fc4123790de8f4f4b210339a65a7c9f009 | |
parent | 143d433896a812ab1235eb390d41523cec17a34a (diff) | |
download | cpython-git-2fcd03bb77fbd3d0b186c15b46de47cf0422ba68.tar.gz |
http://bugs.python.org/issue6971
Adding the SIO_KEEPALIVE_VALS command to socket.ioctl on windows
-rw-r--r-- | Lib/test/test_socket.py | 4 | ||||
-rw-r--r-- | Modules/socketmodule.c | 54 |
2 files changed, 43 insertions, 15 deletions
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 66a402b4e3..472f4035f1 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -543,6 +543,10 @@ class GeneralModuleTests(unittest.TestCase): self.assertTrue(hasattr(socket, 'SIO_RCVALL')) self.assertTrue(hasattr(socket, 'RCVALL_ON')) self.assertTrue(hasattr(socket, 'RCVALL_OFF')) + self.assertTrue(hasattr(socket, 'SIO_KEEPALIVE_VALS')) + s = socket.socket() + self.assertRaises(ValueError, s.ioctl, -1, None) + s.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 100, 100)) class BasicTCPTest(SocketConnectedTest): diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 18cce690a8..396a43deca 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2863,24 +2863,43 @@ static PyObject* sock_ioctl(PySocketSockObject *s, PyObject *arg) { unsigned long cmd = SIO_RCVALL; - unsigned int option = RCVALL_ON; - DWORD recv; + PyObject *argO; + DWORD recv; - if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) + if (!PyArg_ParseTuple(arg, "kO:ioctl", &cmd, &argO)) return NULL; - if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), - NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { - return set_error(); + switch (cmd) { + case SIO_RCVALL: { + unsigned int option = RCVALL_ON; + if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) + return NULL; + if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); } + case SIO_KEEPALIVE_VALS: { + struct tcp_keepalive ka; + if (!PyArg_ParseTuple(arg, "k(kkk):ioctl", &cmd, + &ka.onoff, &ka.keepalivetime, &ka.keepaliveinterval)) + return NULL; + if (WSAIoctl(s->sock_fd, cmd, &ka, sizeof(ka), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); } + default: + PyErr_Format(PyExc_ValueError, "invalid ioctl command %d", cmd); + return NULL; } - return PyLong_FromUnsignedLong(recv); } PyDoc_STRVAR(sock_ioctl_doc, "ioctl(cmd, option) -> long\n\ \n\ -Control the socket with WSAIoctl syscall. Currently only socket.SIO_RCVALL\n\ -is supported as control. Options must be one of the socket.RCVALL_*\n\ -constants."); +Control the socket with WSAIoctl syscall. Currently supported 'cmd' values are\n\ +SIO_RCVALL: 'option' must be one of the socket.RCVALL_* constants.\n\ +SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval)."); #endif @@ -5290,11 +5309,16 @@ init_socket(void) #ifdef SIO_RCVALL { - PyObject *tmp; - tmp = PyLong_FromUnsignedLong(SIO_RCVALL); - if (tmp == NULL) - return; - PyModule_AddObject(m, "SIO_RCVALL", tmp); + DWORD codes[] = {SIO_RCVALL, SIO_KEEPALIVE_VALS}; + const char *names[] = {"SIO_RCVALL", "SIO_KEEPALIVE_VALS"}; + int i; + for(i = 0; i<sizeof(codes)/sizeof(*codes); ++i) { + PyObject *tmp; + tmp = PyLong_FromUnsignedLong(codes[i]); + if (tmp == NULL) + return; + PyModule_AddObject(m, names[i], tmp); + } } PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF); PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON); |