[pypy-svn] r26170 - in pypy/dist/pypy/rpython/rctypes/socketmodule: . test

sanxiyn at codespeak.net sanxiyn at codespeak.net
Sun Apr 23 11:24:12 CEST 2006


Author: sanxiyn
Date: Sun Apr 23 11:24:07 2006
New Revision: 26170

Added:
   pypy/dist/pypy/rpython/rctypes/socketmodule/test/test_errno.py
Modified:
   pypy/dist/pypy/rpython/rctypes/socketmodule/_socket.py
   pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py
Log:
(sanxiyn, arre)
Access errno from ctypes with in_dll() method and use that to raise
exception. To test that we added connect(), and make sure ECONNREFUSED
is raised. To make *that* work do some host-to-network conversions.


Modified: pypy/dist/pypy/rpython/rctypes/socketmodule/_socket.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/socketmodule/_socket.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/socketmodule/_socket.py	Sun Apr 23 11:24:07 2006
@@ -1,10 +1,19 @@
-from ctypes import c_char_p, POINTER, byref, cast, create_string_buffer
+from ctypes import c_char_p, POINTER, pointer, byref, cast, create_string_buffer, sizeof
 import ctypes_socket as _c
 
 
 globals().update(_c.constants)
 
 
+class error(Exception):
+    pass
+
+def _ip_to_number(ip):
+    p1, p2, p3, p4 = [ int(part) for part in ip.split('.') ]
+    num = ((p4 * 256 + p3) * 256 + p2) * 256 + p1
+    return num
+
+
 class socket(object):
 
     def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0):
@@ -13,7 +22,7 @@
         self.proto  = proto
         self._fd = _c.socket(family, type, proto)
         if self._fd == -1:
-            XXX
+            raise error(_c.errno.value)
 
     def __del__(self):
         if self._fd != -1:
@@ -29,17 +38,26 @@
         caddr, caddrlen = self._getsockaddr(addr)
         res = _c.bind(self._fd, caddr, caddrlen)
         if res < 0:
-            XXX
+            raise error(_c.errno.value)
 
     def _getsockaddr(self, addr):
         if self.family == AF_INET:
             (host, port) = addr
-            caddr = sockaddr_in()
+            ip = host # XXX
+            caddr = _c.sockaddr_in()
             caddr.sin_family = AF_INET
-            caddr.sin_port   = port
-            caddr.sin_addr.s_addr = XXX(host)
+            caddr.sin_port = _c.htons(port)
+            caddr.sin_addr.s_addr = _ip_to_number(ip)
+            return caddr
         else:
-            XXX
+            raise NotImplementedError('sorry') # XXX
+
+    def connect(self, addr):
+        caddr = self._getsockaddr(addr)
+        paddr = cast(pointer(caddr), _c.sockaddr_ptr)
+        result = _c.socketconnect(self._fd, paddr, sizeof(caddr))
+        if result == -1:
+            raise error(_c.errno.value)
 
 
 def makeipaddr(caddr, caddrlen):

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	Sun Apr 23 11:24:07 2006
@@ -34,6 +34,7 @@
                                      [('sa_family', c_int),
                                       # unknown and variable fields follow
                                       ])
+sockaddr_ptr = POINTER(sockaddr)
 in_addr = ctypes_platform.getstruct('struct in_addr', HEADER,
                                     [('s_addr', c_uint)])
 sockaddr_in = ctypes_platform.getstruct('struct sockaddr_in', HEADER,
@@ -57,12 +58,22 @@
 assert dllname is not None
 socketdll = cdll.LoadLibrary(dllname)
 
+errno = c_int.in_dll(socketdll, 'errno')
+
+htons = socketdll.htons
+htons.argtypes = [uint16_t]
+htons.restype = uint16_t
+
 socket = socketdll.socket
 socket.argtypes = [c_int, c_int, c_int]
 socket.restype = c_int
 
 socketclose = os.close
 
+socketconnect = socketdll.connect
+socketconnect.argtypes = [c_int, POINTER(sockaddr), socklen_t]
+socketconnect.restype = c_int
+
 getaddrinfo = socketdll.getaddrinfo
 getaddrinfo.argtypes = [c_char_p, c_char_p, POINTER(addrinfo),
                         POINTER(POINTER(addrinfo))]

Added: pypy/dist/pypy/rpython/rctypes/socketmodule/test/test_errno.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rctypes/socketmodule/test/test_errno.py	Sun Apr 23 11:24:07 2006
@@ -0,0 +1,9 @@
+import errno
+import py.test
+from pypy.rpython.rctypes.socketmodule._socket import *
+
+def test_connect_error():
+    s = socket()
+    # This should be refused
+    e = py.test.raises(error, s.connect, ('127.0.0.1', 1000))
+    assert e.value.args[0] == errno.ECONNREFUSED



More information about the Pypy-commit mailing list