[pypy-svn] r77286 - in pypy/branch/fast-forward/pypy: module/_socket module/_socket/test rlib

afa at codespeak.net afa at codespeak.net
Thu Sep 23 02:10:36 CEST 2010


Author: afa
Date: Thu Sep 23 02:10:34 2010
New Revision: 77286

Modified:
   pypy/branch/fast-forward/pypy/module/_socket/interp_socket.py
   pypy/branch/fast-forward/pypy/module/_socket/test/test_sock_app.py
   pypy/branch/fast-forward/pypy/rlib/_rsocket_rffi.py
Log:
Add socket.socket.ioctl() method on Windows.


Modified: pypy/branch/fast-forward/pypy/module/_socket/interp_socket.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_socket/interp_socket.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_socket/interp_socket.py	Thu Sep 23 02:10:34 2010
@@ -4,9 +4,10 @@
 from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped
 from pypy.interpreter.gateway import interp2app
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib import rsocket
 from pypy.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM
 from pypy.rlib.rsocket import SocketError, SocketErrorWithErrno
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter import gateway
 
 class W_RSocket(Wrappable, RSocket):
@@ -337,7 +338,51 @@
         except SocketError, e:
             raise converted_error(space, e)        
     recvfrom_into_w.unwrap_spec = ['self', ObjSpace, W_Root, int, int]
-    
+
+    def ioctl_w(self, space, cmd, w_option):
+        from pypy.rpython.lltypesystem import rffi, lltype
+        from pypy.rlib import rwin32
+        from pypy.rlib.rsocket import _c
+
+        recv_ptr = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')
+        try:
+            if cmd == _c.SIO_RCVALL:
+                option_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+                try:
+                    option_ptr[0] = space.uint_w(w_option)
+                    option_ptr = rffi.cast(rffi.VOIDP, option_ptr)
+                    res = _c.WSAIoctl(
+                        self.fd, cmd,
+                        option_ptr, rffi.sizeof(rffi.INTP),
+                        rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL)
+                    if res < 0:
+                        raise error()
+                finally:
+                    lltype.free(option_ptr, flavor='raw')
+            elif cmd == _c.SIO_KEEPALIVE_VALS:
+                w_onoff, w_time, w_interval = space.unpackiterable(w_option)
+                option_ptr = lltype.malloc(_c.tcp_keepalive, flavor='raw')
+                try:
+                    option_ptr.c_onoff = space.uint_w(w_onoff)
+                    option_ptr.c_keepalivetime = space.uint_w(w_time)
+                    option_ptr.c_keepaliveinterval = space.uint_w(w_interval)
+                    option_ptr = rffi.cast(rffi.VOIDP, option_ptr)
+                    res = _c.WSAIoctl(
+                        self.fd, cmd,
+                        option_ptr, rffi.sizeof(_c.tcp_keepalive),
+                        rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL)
+                    if res < 0:
+                        raise error()
+                finally:
+                    lltype.free(option_ptr, flavor='raw')
+            else:
+                raise operationerrfmt(space.w_ValueError,
+                                      "invalid ioctl command %d", cmd)
+            return space.wrap(recv_ptr[0])
+        finally:
+            lltype.free(recv_ptr, flavor='raw')
+    ioctl_w.unwrap_spec = ['self', ObjSpace, int, W_Root]
+
     def shutdown_w(self, space, how):
         """shutdown(flag)
 
@@ -429,6 +474,8 @@
 for name in ('dup',):
     if not hasattr(RSocket, name):
         socketmethodnames.remove(name)
+if hasattr(rsocket._c, 'WSAIoctl'):
+    socketmethodnames.append('ioctl')
 
 socketmethods = {}
 for methodname in socketmethodnames:

Modified: pypy/branch/fast-forward/pypy/module/_socket/test/test_sock_app.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_socket/test/test_sock_app.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_socket/test/test_sock_app.py	Thu Sep 23 02:10:34 2010
@@ -471,6 +471,19 @@
         (reuse,) = struct.unpack('i', reusestr)
         assert reuse != 0
 
+    def test_socket_ioctl(self):
+        import _socket, sys
+        if sys.platform != 'win32':
+            skip("win32 only")
+        assert hasattr(_socket.socket, 'ioctl')
+        assert hasattr(_socket, 'SIO_RCVALL')
+        assert hasattr(_socket, 'RCVALL_ON')
+        assert hasattr(_socket, 'RCVALL_OFF')
+        assert hasattr(_socket, 'SIO_KEEPALIVE_VALS')
+        s = _socket.socket()
+        raises(ValueError, s.ioctl, -1, None)
+        s.ioctl(_socket.SIO_KEEPALIVE_VALS, (1, 100, 100))
+
     def test_dup(self):
         import _socket as socket
         if not hasattr(socket.socket, 'dup'):

Modified: pypy/branch/fast-forward/pypy/rlib/_rsocket_rffi.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/_rsocket_rffi.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/_rsocket_rffi.py	Thu Sep 23 02:10:34 2010
@@ -55,6 +55,7 @@
     header_lines = [
         '#include <WinSock2.h>',
         '#include <WS2tcpip.h>',
+        '#include <Mstcpip.h>',
         # winsock2 defines AF_UNIX, but not sockaddr_un
         '#undef AF_UNIX',
         ]
@@ -195,13 +196,20 @@
 FD_CONNECT_BIT FD_CLOSE_BIT
 WSA_IO_PENDING WSA_IO_INCOMPLETE WSA_INVALID_HANDLE
 WSA_INVALID_PARAMETER WSA_NOT_ENOUGH_MEMORY WSA_OPERATION_ABORTED
+SIO_RCVALL SIO_KEEPALIVE_VALS
 
 SIOCGIFNAME
 '''.split()
 
 for name in constant_names:
     setattr(CConfig, name, platform.DefinedConstantInteger(name))
-    
+
+if _WIN32:
+    # some SDKs define these values with an enum, #ifdef won't work
+    for name in ('RCVALL_ON', 'RCVALL_OFF'):
+        setattr(CConfig, name, platform.ConstantInteger(name))
+        constant_names.append(name)
+
 constants["BDADDR_ANY"] =  "00:00:00:00:00:00"
 constants["BDADDR_LOCAL"] = "00:00:00:FF:FF:FF"
 
@@ -353,6 +361,12 @@
                                       ('iMaxUdpDg', rffi.USHORT),
                                       ('lpVendorInfo', CCHARP)])
 
+    CConfig.tcp_keepalive = platform.Struct(
+        'struct tcp_keepalive',
+        [('onoff', rffi.ULONG),
+         ('keepalivetime', rffi.ULONG),
+         ('keepaliveinterval', rffi.ULONG)])
+
 
 class cConfig:
     pass
@@ -556,6 +570,7 @@
                     rffi.INT)
     
 elif WIN32:
+    from pypy.rlib import rwin32
     #
     # The following is for pypy.rlib.rpoll
     #
@@ -579,6 +594,14 @@
                                      lltype.Ptr(WSANETWORKEVENTS)],
                                     rffi.INT)
 
+    WSAIoctl = external('WSAIoctl',
+                        [socketfd_type, rwin32.DWORD,
+                         rffi.VOIDP, rwin32.DWORD,
+                         rffi.VOIDP, rwin32.DWORD,
+                         rwin32.LPDWORD, rffi.VOIDP, rffi.VOIDP],
+                        rffi.INT)
+    tcp_keepalive = cConfig.tcp_keepalive
+
 if WIN32:
     WSAData = cConfig.WSAData
     WSAStartup = external('WSAStartup', [rffi.INT, lltype.Ptr(WSAData)],



More information about the Pypy-commit mailing list