[pypy-svn] r26393 - in pypy/dist/pypy: module/_socket module/_socket/test rpython/rctypes/socketmodule

ac at codespeak.net ac at codespeak.net
Thu Apr 27 05:34:55 CEST 2006


Author: ac
Date: Thu Apr 27 05:34:55 2006
New Revision: 26393

Modified:
   pypy/dist/pypy/module/_socket/interp_socket.py
   pypy/dist/pypy/module/_socket/test/test_socket2.py
   pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py
Log:
(aleale, arre)
The tests of module/_socket now pass again (if you don't enable _socket).



Modified: pypy/dist/pypy/module/_socket/interp_socket.py
==============================================================================
--- pypy/dist/pypy/module/_socket/interp_socket.py	(original)
+++ pypy/dist/pypy/module/_socket/interp_socket.py	Thu Apr 27 05:34:55 2006
@@ -215,13 +215,13 @@
     The optional protocol name, if given, should be 'tcp' or 'udp',
     otherwise any protocol will match.
     """
-    try:
-        if w_proto is None:
-            return space.wrap(socket.getservbyname(name))
-        else:
-            return space.wrap(socket.getservbyname(name, space.str_w(w_proto)))
-    except socket.error, e:
-        raise wrap_socketerror(space, e)
+    proto = None
+    if w_proto:
+        proto = space.str_w(w_proto)
+    servent_ptr = _c.getservbyname(name, proto)
+    if not servent_ptr:
+        raise w_get_socketerror("service/port not found")
+    return space.wrap(_c.ntohs(servent_ptr.contents.s_port))
 getservbyname.unwrap_spec = [ObjSpace, str, W_Root]
 
 def getservbyport(space, port, w_proto=NoneNotWrapped):
@@ -231,13 +231,13 @@
     The optional protocol name, if given, should be 'tcp' or 'udp',
     otherwise any protocol will match.
     """
-    try:
-        if w_proto is None:
-            return space.wrap(socket.getservbyport(port))
-        else:
-            return space.wrap(socket.getservbyport(port, space.str_w(w_proto)))
-    except socket.error, e:
-        raise wrap_socketerror(space, e)
+    proto = None
+    if w_proto:
+        proto = space.str_w(w_proto)
+    servent_ptr = _c.getservbyport(_c.htons(port), proto)
+    if not servent_ptr:
+        raise w_get_socketerror("port/proto not found")
+    return space.wrap(servent_ptr.contents.s_name)
 getservbyport.unwrap_spec = [ObjSpace, int, W_Root]
 
 def getprotobyname(space, name):
@@ -245,10 +245,11 @@
 
     Return the protocol number for the named protocol.  (Rarely used.)
     """
-    try:
-        return space.wrap(socket.getprotobyname(name))
-    except socket.error, e:
-        raise wrap_socketerror(space, e)
+    protoent_ptr = _c.getprotobyname(name)
+    if not protoent_ptr:
+        raise w_get_socketerror('protocol not found')
+    return space.wrap(protoent_ptr.contents.p_proto)
+
 getprotobyname.unwrap_spec = [ObjSpace, str]
 
 def fromfd(space, fd, family, type, w_proto=NoneNotWrapped):
@@ -257,13 +258,15 @@
     Create a socket object from the given file descriptor.
     The remaining arguments are the same as for socket().
     """
-    try:
-        if w_proto is None:
-            return space.wrap(socket.fromfd(fd, family, type))
-        else:
-            return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto)))
-    except socket.error, e:
-        raise wrap_socketerror(space, e)
+
+    newfd = _c.dup(fd)
+    if newfd < 0:
+        raise w_get_socketerror(None, _c.errno)
+    if w_proto is None:
+        return space.wrap(Socket(space, newfd, family, type))
+    else:
+        proto = space.int_w(w_proto)
+        return space.wrap(Socket(space, newfd, family, type, proto))
 fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root]
 
 def socketpair(space, w_family=NoneNotWrapped, w_type=NoneNotWrapped, w_proto=NoneNotWrapped):
@@ -617,11 +620,54 @@
     """getnameinfo(sockaddr, flags) --> (host, port)
 
     Get host and port for a sockaddr."""
-    sockaddr = space.unwrap(w_sockaddr)
-    try:
-        return space.wrap(_c.getnameinfo(sockaddr, flags))
-    except _c.error, e:
-        raise wrap_socketerror(space, e)
+    w_flowinfo = w_scope_id = space.wrap(0)
+    sockaddr_len = space.int_w(space.len(w_sockaddr))
+    if sockaddr_len == 2:
+        w_host, w_port = space.unpackiterable(w_sockaddr, 2)
+    elif sockaddr_len == 3:
+        w_host, w_port, w_flowinfo = space.unpackiterable(w_sockaddr, 3)
+    elif sockaddr_len == 4:
+        w_host, w_port, w_flowinfo, w_scope_id = space.unpackiterable(w_sockaddr, 4)
+    else:
+        raise OperationError(space.w_TypeError,
+                             space.wrap('argument 1 should be 2-4 items (%d given)' % sockaddr_len))
+    host = space.str_w(w_host)
+    port = space.int_w(w_port)
+    flowinfo = space.int_w(w_flowinfo)
+    scope_id = space.int_w(w_scope_id)
+
+    res = _c.addrinfo_ptr()
+    hints = _c.addrinfo()
+    hints.ai_family = _c.AF_UNSPEC
+    hints.ai_socktype = _c.SOCK_DGRAM
+    retval = _c.getaddrinfo(host, str(port), ctypes.pointer(hints), ctypes.pointer(res))
+    if retval != 0:
+        raise w_get_socketgaierror(space, None, retval)
+    family = res.contents.ai_family
+    if family == _c.AF_INET:
+        if sockaddr_len != 2:
+            if res:
+                _c.freeaddrinfo(res)
+            raise OperationError(space.w_TypeError,
+                                 space.wrap('argument 1 should be 2 items (%d given)' % sockaddr_len))
+            
+    elif family == _c.AF_INET6:
+        sin6_ptr = ctypes.cast(res.contents.ai_addr, POINTER(_c.sockaddr_in6))
+        sin6_ptr.contents.sin6_flowinfo = flowinfo
+        sin6_ptr.contents.sin6_scope_id = scope_id
+
+    hostbuf = ctypes.create_string_buffer(_c.NI_MAXHOST)
+    portbuf = ctypes.create_string_buffer(_c.NI_MAXSERV)
+    error = _c.getnameinfo(res.contents.ai_addr, res.contents.ai_addrlen,
+                        hostbuf, ctypes.sizeof(hostbuf),
+                        portbuf, ctypes.sizeof(portbuf), flags)
+
+    if res:
+        _c.freeaddrinfo(res)
+    if error:
+        raise w_get_socketgaierror(None, error)
+    return space.newtuple([space.wrap(hostbuf.value),
+                           space.wrap(portbuf.value)])
 getnameinfo.unwrap_spec = [ObjSpace, W_Root, int]
 
 # _____________________________________________________________
@@ -667,13 +713,6 @@
 
 def newsocket(space, w_subtype, family=_c.AF_INET,
               type=_c.SOCK_STREAM, proto=0):
-    # sets the timeout for the CPython implementation
-    timeout = getstate(space).defaulttimeout
-    if timeout < 0.0:
-        _c.setdefaulttimeout(None)
-    else:
-        _c.setdefaulttimeout(timeout)
-
     try:
         fd = _c.socket(family, type, proto)
     except _c.error, e: # On untranslated PyPy
@@ -690,16 +729,26 @@
 descr_socket_new = interp2app(newsocket,
                                unwrap_spec=[ObjSpace, W_Root, int, int, int])
 
+def setblocking(fd, block):
+    delay_flag = _c.fcntl(fd, _c.F_GETFL, 0)
+    if block:
+        delay_flag &= ~_c.O_NONBLOCK
+    else:
+        delay_flag |= _c.O_NONBLOCK
+    _c.fcntl(fd, _c.F_SETFL, delay_flag)
+    
 class Socket(Wrappable):
     "A wrappable box around an interp-level socket object."
 
-    def __init__(self, space, fd, family, type, proto):
+    def __init__(self, space, fd, family, type, proto=0):
         self.fd = fd
         self.family = family
         self.type = type
         self.proto = proto
-        self.timeout = getstate(space).defaulttimeout
         self.closed = False
+        self.timeout = getstate(space).defaulttimeout
+        if self.timeout >= 0.0:
+            setblocking(self.fd, False)
 
     def accept(self, space):
         """accept() -> (socket object, address info)

Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py
==============================================================================
--- pypy/dist/pypy/module/_socket/test/test_socket2.py	(original)
+++ pypy/dist/pypy/module/_socket/test/test_socket2.py	Thu Apr 27 05:34:55 2006
@@ -4,8 +4,6 @@
 import py
 import socket, sys
 
-py.test.skip('In-progress')
-
 def setup_module(mod):
     mod.space = StdObjSpace(usemodules=['_socket'])
     mod.w_socket = space.appexec([], "(): import _socket as m; return m")
@@ -92,13 +90,13 @@
            """(_socket, fd, family, type, proto): 
                  return _socket.fromfd(fd, family, type, proto)""")
 
-    assert space.unwrap(fd).fileno()
+    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(fd).fileno()
+    assert space.unwrap(space.call_method(fd, 'fileno'))
 
 def test_ntohs():
     w_n = space.appexec([w_socket, space.wrap(125)],

Modified: pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py	Thu Apr 27 05:34:55 2006
@@ -9,6 +9,7 @@
             'netinet/in.h',
             'netinet/tcp.h',
             'unistd.h',
+            'fcntl.h',
             'stdio.h',
             'netdb.h',
             'arpa/inet.h'
@@ -19,6 +20,9 @@
 class CConfig:
     _header_ = HEADER
     # constants
+    O_NONBLOCK = ctypes_platform.ConstantInteger('O_NONBLOCK')
+    F_GETFL = ctypes_platform.ConstantInteger('F_GETFL')
+    F_SETFL = ctypes_platform.ConstantInteger('F_SETFL')
     
 constant_names = ['AF_APPLETALK', 'AF_ASH', 'AF_ATMPVC', 'AF_ATMSVC', 'AF_AX25',
                   'AF_BLUETOOTH', 'AF_BRIDGE', 'AF_ECONET', 'AF_INET', 'AF_INET6',
@@ -102,6 +106,11 @@
                                         [('sin_family', c_int),
                                          ('sin_port',   c_ushort),
                                          ('sin_addr',   CConfig.in_addr)])
+
+CConfig.sockaddr_in6  = ctypes_platform.Struct('struct sockaddr_in6',
+                                               [('sin6_flowinfo', c_int),
+                                                ('sin6_scope_id', c_int),
+                                                ])
 addrinfo_ptr = POINTER("addrinfo")
 CConfig.addrinfo = ctypes_platform.Struct('struct addrinfo',
                                      [('ai_flags', c_int),
@@ -122,6 +131,13 @@
                                       ])
 
 
+CConfig.servent = ctypes_platform.Struct('struct servent',
+                                         [('s_name', c_char_p),
+                                          ('s_port', c_int)])
+
+CConfig.protoent = ctypes_platform.Struct('struct protoent',
+                                          [('p_proto', c_int),
+                                           ])
 
 class cConfig:
     pass
@@ -138,8 +154,14 @@
     else:
         constants[name] = default
 
+constants['has_ipv6'] = True # This is a configuration option in CPython
+
 locals().update(constants)
 
+O_NONBLOCK = cConfig.O_NONBLOCK
+F_GETFL = cConfig.F_GETFL
+F_SETFL = cConfig.F_SETFL
+
 uint16_t = cConfig.uint16_t
 uint32_t = cConfig.uint32_t
 size_t = cConfig.size_t
@@ -158,6 +180,10 @@
 assert dllname is not None
 socketdll = cdll.LoadLibrary(dllname)
 
+dup = socketdll.dup
+dup.argtypes = [c_int]
+dup.restype = c_int
+
 errno = c_int.in_dll(socketdll, 'errno')
 
 strerror = socketdll.strerror
@@ -295,3 +321,23 @@
 gethostbyname = socketdll.gethostbyname
 gethostbyname.argtypes = [POINTER(c_char)]
 gethostbyname.restype = POINTER(cConfig.hostent)
+
+gethostbyaddr = socketdll.gethostbyaddr
+gethostbyaddr.argtypes = [POINTER(c_char), c_int, c_int]
+gethostbyaddr.restype = POINTER(cConfig.hostent)
+
+getservbyname = socketdll.getservbyname
+getservbyname.argtypes = [c_char_p, c_char_p]
+getservbyname.restype = POINTER(cConfig.servent)
+
+getservbyport = socketdll.getservbyport
+getservbyport.argtypes = [c_int, c_char_p]
+getservbyport.restype = POINTER(cConfig.servent)
+
+getprotobyname = socketdll.getprotobyname
+getprotobyname.argtypes = [c_char_p]
+getprotobyname.restype = POINTER(cConfig.protoent)
+
+fcntl = socketdll.fcntl
+fcntl.argtypes = [c_int] * 3
+fcntl.restype = c_int



More information about the Pypy-commit mailing list