[pypy-svn] r26400 - in pypy/dist/pypy: module/_socket rpython/rctypes/socketmodule
ac at codespeak.net
ac at codespeak.net
Thu Apr 27 08:02:34 CEST 2006
Author: ac
Date: Thu Apr 27 08:02:33 2006
New Revision: 26400
Modified:
pypy/dist/pypy/module/_socket/interp_socket.py
pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py
Log:
(aleale, arre)
Now the app-level tests pass too.
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 08:02:33 2006
@@ -1,11 +1,12 @@
import sys
from pypy.interpreter.typedef import TypeDef
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import Wrappable, UnpackValueError
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import W_Root, NoneNotWrapped
from pypy.interpreter.gateway import ObjSpace, interp2app
from pypy.rpython.rctypes.socketmodule import ctypes_socket as _c
import ctypes
+import errno
IPV4_ADDRESS_SIZE = 4
IPV6_ADDRESS_SIZE = 16
@@ -82,7 +83,7 @@
if errno > -1:
if message is None:
message = socket_strerror(errno)
- return OperationError(w_errortype, space.wrap(errno), space.wrap(message))
+ return OperationError(w_errortype, space.newtuple([space.wrap(errno), space.wrap(message)]))
else:
return OperationError(w_errortype, space.wrap(message))
@@ -92,7 +93,7 @@
if errno > -1:
if message is None:
message = _c.gai_strerror(errno)
- return OperationError(w_errortype, space.wrap(errno), space.wrap(message))
+ return OperationError(w_errortype, space.newtuple([space.wrap(errno), space.wrap(message)]))
else:
return OperationError(w_errortype, space.wrap(message))
@@ -102,7 +103,7 @@
if errno > -1:
if message is None:
message = _c.hstrerror(errno)
- return OperationError(w_errortype, space.wrap(errno), space.wrap(message))
+ return OperationError(w_errortype, space.newtuple([space.wrap(errno), space.wrap(message)]))
else:
return OperationError(w_errortype, space.wrap(message))
@@ -123,7 +124,7 @@
res = _c.addr_info_ptr
err = _c.getaddrinfo( None, "0", pointer(hints), pointer(res))
if err:
- raise w_get_socketgaierror(space, None, _c.errno)
+ raise w_get_socketgaierror(space, None, err)
if res.contents.ai_next:
raise OperationError(_socket.error, space.wrap("wildcard resolved to multiple address"))
addr = res.contents.ai_addr
@@ -261,7 +262,7 @@
newfd = _c.dup(fd)
if newfd < 0:
- raise w_get_socketerror(None, _c.errno)
+ raise w_get_socketerror(None, _c.errno.value)
if w_proto is None:
return space.wrap(Socket(space, newfd, family, type))
else:
@@ -713,12 +714,9 @@
def newsocket(space, w_subtype, family=_c.AF_INET,
type=_c.SOCK_STREAM, proto=0):
- try:
- fd = _c.socket(family, type, proto)
- except _c.error, e: # On untranslated PyPy
- raise wrap_socketerror(space, e)
- except OSError, e: # On translated PyPy
- raise w_get_socketerror(space, e.strerror, e.errno)
+ fd = _c.socket(family, type, proto)
+ if fd < 0:
+ raise w_get_socketerror(space, None, _c.errno.value)
# XXX If we want to support subclassing the socket type we will need
# something along these lines. But allocate_instance is only defined
# on the standard object space, so this is not really correct.
@@ -750,6 +748,36 @@
if self.timeout >= 0.0:
setblocking(self.fd, False)
+ def _getsockaddr(self, space, w_addr):
+ """Returns a pointer to a sockaddr"""
+ if self.family == _c.AF_INET:
+ try:
+ w_host, w_port = space.unpackiterable(w_addr, 2)
+ except UnpackValueError:
+ e_msg = space.wrap("getsockaddrarg: AF_INET address must be a tuple of two elements")
+ raise OperationError(space.w_TypeError, e_msg)
+
+ port = space.int_w(w_port)
+ host = space.str_w(w_host)
+ res = _c.addrinfo_ptr()
+ hints = _c.addrinfo()
+ hints.ai_family = self.family
+ hints.ai_socktype = self.type
+ hints.ai_protocol = self.proto
+ retval = _c.getaddrinfo(host, str(port), ctypes.pointer(hints), ctypes.pointer(res))
+ if retval != 0:
+ raise w_get_socketgaierror(space, None, retval)
+ addrinfo = res.contents
+ addrlen = addrinfo.ai_addrlen
+ caddr_ptr = ctypes.create_string_buffer(addrlen)
+ _c.memcpy(caddr_ptr, addrinfo.ai_addr, addrlen)
+
+ sockaddr_ptr = ctypes.cast(caddr_ptr, _c.sockaddr_ptr)
+ return sockaddr_ptr, addrlen
+
+ else:
+ raise NotImplementedError('Unsupported address family') # XXX
+
def accept(self, space):
"""accept() -> (socket object, address info)
@@ -798,31 +826,14 @@
Connect the socket to a remote address. For IP sockets, the address
is a pair (host, port).
"""
- if self.family == socket.AF_INET:
- if not (space.is_true(space.isinstance(w_addr, space.w_tuple)) and
- space.int_w(space.len(w_addr)) == 2):
- raise OperationError(space.w_TypeError,
- space.wrap("AF_INET address must be tuple of length 2"))
- addr_w = space.unpackiterable(w_addr)
- if not (space.is_true(space.isinstance(addr_w[0], space.w_str))
- and space.is_true(space.isinstance(addr_w[1], space.w_int))):
- raise OperationError(space.w_TypeError,
- space.wrap("tuple of a string and an int required"))
- host = space.str_w(addr_w[0])
- port = space.int_w(addr_w[1])
- sockname = (host, port, 0, 0)
- else:
- # XXX IPv6 and Unix sockets missing here
- pass
- try:
- rsocket.connect(self.fd, sockname, self.family)
- except OSError, ex:
- raise w_get_socketerror(space, e.strerror, e.errno)
- # XXX timeout doesn't really work at the moment
- except socket.timeout:
- raise wrap_timeouterror(space)
- except socket.error, e:
- raise wrap_socketerror(space, e)
+ sockaddr_ptr, sockaddr_len = self._getsockaddr(space, w_addr)
+ err = _c.socketconnect(self.fd, sockaddr_ptr, sockaddr_len)
+ if err:
+ errno = _c.errno.value
+ if self.timeout > 0.0:
+ # XXX timeout doesn't really work at the moment
+ pass
+ raise w_get_socketerror(space, None, errno)
connect.unwrap_spec = ['self', ObjSpace, W_Root]
def connect_ex(self, space, w_addr):
@@ -868,12 +879,14 @@
Return the address of the remote endpoint. For IP sockets, the address
info is a pair (hostaddr, port).
"""
- try:
- name = rsocket.getpeername(self.fd)
- # XXX IPv4 only
- return space.newtuple([space.wrap(name[0]), space.wrap(name[1])])
- except socket.error, e:
- raise wrap_socketerror(space, e)
+ def getpeername(self, space):
+ peeraddr = ctypes.pointer(_c.sockaddr())
+ peeraddrlen = _c.socklen_t(ctypes.sizeof(_c.sockaddr))
+ res = _c.socketgetpeername(self.fd, peeraddr,
+ ctypes.pointer(peeraddrlen))
+ if res < 0:
+ raise w_get_socketerror(None, _c.errno.value)
+ return w_makesockaddr(space, peeraddr, peeraddrlen, self.proto)
getpeername.unwrap_spec = ['self', ObjSpace]
def getsockname(self, space):
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 08:02:33 2006
@@ -341,3 +341,7 @@
fcntl = socketdll.fcntl
fcntl.argtypes = [c_int] * 3
fcntl.restype = c_int
+
+memcpy = socketdll.memcpy
+memcpy.argtypes = [c_void_p, c_void_p, size_t]
+memcpy.restype = c_void_p
More information about the Pypy-commit
mailing list