[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