http://bugs.python.org/issue6971

Porting revision 75054 from trunk
parent 7d3d209b
...@@ -553,6 +553,10 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -553,6 +553,10 @@ class GeneralModuleTests(unittest.TestCase):
self.assertTrue(hasattr(socket, 'SIO_RCVALL')) self.assertTrue(hasattr(socket, 'SIO_RCVALL'))
self.assertTrue(hasattr(socket, 'RCVALL_ON')) self.assertTrue(hasattr(socket, 'RCVALL_ON'))
self.assertTrue(hasattr(socket, 'RCVALL_OFF')) 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): class BasicTCPTest(SocketConnectedTest):
......
...@@ -2686,24 +2686,43 @@ static PyObject* ...@@ -2686,24 +2686,43 @@ static PyObject*
sock_ioctl(PySocketSockObject *s, PyObject *arg) sock_ioctl(PySocketSockObject *s, PyObject *arg)
{ {
unsigned long cmd = SIO_RCVALL; unsigned long cmd = SIO_RCVALL;
unsigned int option = RCVALL_ON; PyObject *argO;
DWORD recv; DWORD recv;
if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) if (!PyArg_ParseTuple(arg, "kO:ioctl", &cmd, &argO))
return NULL; return NULL;
if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), switch (cmd) {
NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { case SIO_RCVALL: {
return set_error(); 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, PyDoc_STRVAR(sock_ioctl_doc,
"ioctl(cmd, option) -> long\n\ "ioctl(cmd, option) -> long\n\
\n\ \n\
Control the socket with WSAIoctl syscall. Currently only socket.SIO_RCVALL\n\ Control the socket with WSAIoctl syscall. Currently supported 'cmd' values are\n\
is supported as control. Options must be one of the socket.RCVALL_*\n\ SIO_RCVALL: 'option' must be one of the socket.RCVALL_* constants.\n\
constants."); SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval).");
#endif #endif
...@@ -5058,11 +5077,16 @@ PyInit__socket(void) ...@@ -5058,11 +5077,16 @@ PyInit__socket(void)
#ifdef SIO_RCVALL #ifdef SIO_RCVALL
{ {
PyObject *tmp; DWORD codes[] = {SIO_RCVALL, SIO_KEEPALIVE_VALS};
tmp = PyLong_FromUnsignedLong(SIO_RCVALL); const char *names[] = {"SIO_RCVALL", "SIO_KEEPALIVE_VALS"};
if (tmp == NULL) int i;
return NULL; for(i = 0; i<sizeof(codes)/sizeof(*codes); ++i) {
PyModule_AddObject(m, "SIO_RCVALL", tmp); PyObject *tmp;
tmp = PyLong_FromUnsignedLong(codes[i]);
if (tmp == NULL)
return NULL;
PyModule_AddObject(m, names[i], tmp);
}
} }
PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF); PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF);
PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON); PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment