Commits

Amaury Forgeot d'Arc  committed a6bc13d

Remove socket.fromfd(), and dup() is now a module-level function.

  • Participants
  • Parent commits 9f64095
  • Branches py3k

Comments (0)

Files changed (6)

File pypy/module/_socket/__init__.py

         for name in """
             gethostbyname gethostbyname_ex gethostbyaddr gethostname
             getservbyname getservbyport getprotobyname
-            fromfd socketpair
+            dup socketpair
             ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop
             getaddrinfo getnameinfo
             getdefaulttimeout setdefaulttimeout
             """.split():
 
-            if name in ('inet_pton', 'inet_ntop',
-                        'fromfd', 'socketpair',
+            if name in ('inet_pton', 'inet_ntop', 'socketpair',
                         ) and not hasattr(rsocket, name):
                 continue
             

File pypy/module/_socket/interp_func.py

         raise converted_error(space, e)
     return space.newtuple([space.wrap(host), space.wrap(servport)])
 
-@unwrap_spec(fd=int, family=int, type=int, proto=int)
-def fromfd(space, fd, family, type, proto=0):
-    """fromfd(fd, family, type[, proto]) -> socket object
-
-    Create a socket object from the given file descriptor.
-    The remaining arguments are the same as for socket().
-    """
-    try:
-        sock = rsocket.fromfd(fd, family, type, proto, W_RSocket)
-    except SocketError, e:
-        raise converted_error(space, e)
-    return space.wrap(sock)
+@unwrap_spec(fd=int)
+def dup(space, fd):
+    newfd = rsocket.dup(fd)
+    return space.wrap(newfd)
 
 @unwrap_spec(family=int, type=int, proto=int)
 def socketpair(space, family=rsocket.socketpair_default_family,

File pypy/module/_socket/interp_socket.py

         error = self.connect_ex(addr)
         return space.wrap(error)
 
-    def dup_w(self, space):
-        try:
-            return self.dup(W_RSocket)
-        except SocketError, e:
-            raise converted_error(space, e)
-    
     def fileno_w(self, space):
         """fileno() -> integer
 
 # ____________________________________________________________
 
 socketmethodnames = """
-_accept bind close connect connect_ex dup fileno detach
+_accept bind close connect connect_ex fileno detach
 getpeername getsockname getsockopt gettimeout listen
 recv recvfrom send sendall sendto setblocking
 setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into
 """.split()
-# Remove non-implemented methods
-for name in ('dup',):
-    if not hasattr(RSocket, name):
-        socketmethodnames.remove(name)
 if hasattr(rsocket._c, 'WSAIoctl'):
     socketmethodnames.append('ioctl')
 
 close() -- close the socket
 connect(addr) -- connect the socket to a remote address
 connect_ex(addr) -- connect, return an error code instead of an exception
-dup() -- return a new socket object identical to the current one [*]
 fileno() -- return underlying file descriptor
 getpeername() -- return remote address [*]
 getsockname() -- return local address

File pypy/module/_socket/test/test_sock_app.py

                         "(_socket, name): return _socket.getprotobyname(name)")
     assert space.unwrap(w_n) == socket.IPPROTO_TCP
 
-def test_fromfd():
-    # XXX review
-    if not hasattr(socket, 'fromfd'):
-        py.test.skip("No socket.fromfd on this platform")
-    orig_fd = path.open()
-    fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()),
-            space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM),
-            space.wrap(0)],
-           """(_socket, fd, family, type, proto): 
-                 return _socket.fromfd(fd, family, type, proto)""")
-
-    assert space.unwrap(space.call_method(fd, 'fileno'))
-    fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()),
-            space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM)],
-                """(_socket, fd, family, type):
-                    return _socket.fromfd(fd, family, type)""")
-
-    assert space.unwrap(space.call_method(fd, 'fileno'))
-
 def test_ntohs():
     w_n = space.appexec([w_socket, space.wrap(125)],
                         "(_socket, x): return _socket.ntohs(x)")
 
     def test_dup(self):
         import _socket as socket
-        if not hasattr(socket.socket, 'dup'):
-            skip('No dup() on this platform')
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         s.bind(('localhost', 0))
-        s2 = s.dup()
-        assert s.fileno() != s2.fileno()
-        assert s.getsockname() == s2.getsockname()
+        fd = socket.dup(s.fileno())
+        assert s.fileno() != fd
 
     def test_buffer(self):
         # Test that send/sendall/sendto accept a buffer as arg

File pypy/rlib/_rsocket_rffi.py

          ('iErrorCode', rffi.CFixedArray(rffi.INT, 10)), #FD_MAX_EVENTS
          ])
 
+    CConfig.WSAPROTOCOL_INFO = platform.Struct(
+        'struct WSAPROTOCOL_INFO',
+        [])  # Struct is just passed between functions
+    CConfig.FROM_PROTOCOL_INFO = platform.DefinedConstantInteger(
+        'FROM_PROTOCOL_INFO')
+
 CConfig.timeval = platform.Struct('struct timeval',
                                          [('tv_sec', rffi.LONG),
                                           ('tv_usec', rffi.LONG)])
                         rffi.INT)
     tcp_keepalive = cConfig.tcp_keepalive
 
+    WSAPROTOCOL_INFO = cConfig.WSAPROTOCOL_INFO
+    FROM_PROTOCOL_INFO = cConfig.FROM_PROTOCOL_INFO
+    WSADuplicateSocket = external('WSADuplicateSocket', 
+                                  [socketfd_type, rwin32.DWORD,
+                                   lltype.Ptr(WSAPROTOCOL_INFO)],
+                                  rffi.INT)
+    WSASocket = external('WSASocket', 
+                         [rffi.INT, rffi.INT, rffi.INT,
+                          lltype.Ptr(WSAPROTOCOL_INFO),
+                          rffi.DWORD, rffi.DWORD],
+                         socketfd_type)
+
 if WIN32:
     WSAData = cConfig.WSAData
     WSAStartup = external('WSAStartup', [rffi.INT, lltype.Ptr(WSAData)],

File pypy/rlib/rsocket.py

         return (make_socket(fd0, family, type, proto, SocketClass),
                 make_socket(fd1, family, type, proto, SocketClass))
 
-if hasattr(_c, 'dup'):
-    def fromfd(fd, family, type, proto=0, SocketClass=RSocket):
-        # Dup the fd so it and the socket can be closed independently
-        fd = _c.dup(fd)
-        if fd < 0:
-            raise last_error()
-        return make_socket(fd, family, type, proto, SocketClass)
+if _c.WIN32:
+    def dup(fd):
+        with lltype.scoped_alloc(_c.WSAData, zero=True) as info:
+            if _c.WSADuplicateSocket(fd, rwin32.GetCurrentProcessId(), info):
+                raise last_error()
+            result = _c.WSASocket(
+                _c.FROM_PROTOCOL_INFO, _c.FROM_PROTOCOL_INFO,
+                _c.FROM_PROTOCOL_INFO, info, 0, 0)
+            if result == INVALID_SOCKET:
+                raise last_error()
+            return result
+else:
+    def dup(fd):
+        return _c.dup(fd)
 
 def getdefaulttimeout():
     return defaults.timeout