Author: Alexander Hesse <webmas...@aquanasoft.de> Branch: split-rpython Changeset: r59943:898e7335e13b Date: 2013-01-11 08:00 +0100 http://bitbucket.org/pypy/pypy/changeset/898e7335e13b/
Log: Refactored rsocket and interp_socket for the split. Hacky! diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,5 +1,5 @@ from pypy.interpreter.gateway import unwrap_spec, WrappedDefault -from pypy.module._socket.interp_socket import converted_error, W_RSocket +from pypy.module._socket.interp_socket import converted_error, W_RSocket, addr_as_object, ipaddr_from_object from rpython.rlib import rsocket from rpython.rlib.rsocket import SocketError, INVALID_SOCKET from pypy.interpreter.error import OperationError @@ -120,7 +120,7 @@ Get host and port for a sockaddr.""" try: - addr = rsocket.ipaddr_from_object(space, w_sockaddr) + addr = ipaddr_from_object(space, w_sockaddr) host, servport = rsocket.getnameinfo(addr, flags) except SocketError, e: raise converted_error(space, e) @@ -284,7 +284,7 @@ space.wrap(socktype), space.wrap(protocol), space.wrap(canonname), - addr.as_object(INVALID_SOCKET, space)]) # -1 as per cpython + addr_as_object(addr, INVALID_SOCKET, space)]) # -1 as per cpython for (family, socktype, protocol, canonname, addr) in lst] return space.newlist(lst1) diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -5,7 +5,8 @@ from rpython.rlib.rarithmetic import intmask from rpython.rlib import rsocket from rpython.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM -from rpython.rlib.rsocket import SocketError, SocketErrorWithErrno +from rpython.rlib.rsocket import SocketError, SocketErrorWithErrno, RSocketError +from rpython.rlib.socket import INETAddress, INET6Address from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway @@ -16,6 +17,124 @@ def check(self): self.space.getexecutioncontext().checksignals() + +# XXX Hack to seperate rpython and pypy +def addr_as_object(addr, fd, space): + if addr.family == rsocket.AF_INET: + return space.newtuple([space.wrap(addr.get_host()), + space.wrap(addr.get_port())]) + if addr.family == rsocket.AF_INET6: + return space.newtuple([space.wrap(addr.get_host()), + space.wrap(addr.get_port()), + space.wrap(addr.get_flowinfo()), + space.wrap(addr.get_scope_id())]) + if 'AF_PACKET' in rsocket.constants and addr.family == rsocket.AF_PACKET: + return space.newtuple([space.wrap(addr.get_ifname(fd)), + space.wrap(addr.get_protocol()), + space.wrap(addr.get_pkttype()), + space.wrap(addr.get_hatype()), + space.wrap(addr.get_addr())]) + if 'AF_UNIX' in rsocket.constants and addr.family == rsocket.AF_UNIX: + return space.wrap(addr.get_path()) + if 'AF_NETLINK' in rsocket.constants and addr.family == rsocket.AF_NETLINK: + return space.newtuple([space.wrap(addr.get_pid()), + space.wrap(addr.get_groups())]) + # If we don't know the address family, don't raise an + # exception -- return it as a tuple. + a = addr.lock() + family = rffi.cast(lltype.Signed, a.c_sa_family) + datalen = addr.addrlen - offsetof(_c.sockaddr, 'c_sa_data') + rawdata = ''.join([a.c_sa_data[i] for i in range(datalen)]) + addr.unlock() + return space.newtuple([space.wrap(family), + space.wrap(rawdata)]) + +# XXX Hack to seperate rpython and pypy +# XXX a bit of code duplication +def fill_from_object(addr, space, w_address): + if addr.family == rsocket.AF_INET: + from pypy.interpreter.error import OperationError + _, w_port = space.unpackiterable(w_address, 2) + port = space.int_w(w_port) + port = make_ushort_port(space, port) + a = addr.lock(_c.sockaddr_in) + rffi.setintfield(a, 'c_sin_port', htons(port)) + addr.unlock() + elif addr.family == rsocket.AF_INET6: + from pypy.interpreter.error import OperationError + pieces_w = space.unpackiterable(w_address) + if not (2 <= len(pieces_w) <= 4): + raise RSocketError("AF_INET6 address must be a tuple of length 2 " + "to 4, not %d" % len(pieces_w)) + port = space.int_w(pieces_w[1]) + port = make_ushort_port(space, port) + if len(pieces_w) > 2: flowinfo = space.int_w(pieces_w[2]) + else: flowinfo = 0 + if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3]) + else: scope_id = 0 + if flowinfo < 0 or flowinfo > 0xfffff: + raise OperationError(space.w_OverflowError, space.wrap( + "flowinfo must be 0-1048575.")) + flowinfo = rffi.cast(lltype.Unsigned, flowinfo) + a = addr.lock(_c.sockaddr_in6) + rffi.setintfield(a, 'c_sin6_port', htons(port)) + rffi.setintfield(a, 'c_sin6_flowinfo', htonl(flowinfo)) + rffi.setintfield(a, 'c_sin6_scope_id', scope_id) + addr.unlock() + else: + raise NotImplementedError + +# XXX Hack to seperate rpython and pypy +def addr_from_object(family, space, w_address): + if family == rsocket.AF_INET: + w_host, w_port = space.unpackiterable(w_address, 2) + host = space.str_w(w_host) + port = space.int_w(w_port) + port = make_ushort_port(space, port) + return INETAddress(host, port) + if family == rsocket.AF_INET6: + from pypy.interpreter.error import OperationError + pieces_w = space.unpackiterable(w_address) + if not (2 <= len(pieces_w) <= 4): + raise TypeError("AF_INET6 address must be a tuple of length 2 " + "to 4, not %d" % len(pieces_w)) + host = space.str_w(pieces_w[0]) + port = space.int_w(pieces_w[1]) + port = make_ushort_port(space, port) + if len(pieces_w) > 2: flowinfo = space.int_w(pieces_w[2]) + else: flowinfo = 0 + if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3]) + else: scope_id = 0 + if flowinfo < 0 or flowinfo > 0xfffff: + raise OperationError(space.w_OverflowError, space.wrap( + "flowinfo must be 0-1048575.")) + flowinfo = rffi.cast(lltype.Unsigned, flowinfo) + return INET6Address(host, port, flowinfo, scope_id) + if 'AF_UNIX' in rsocket.constants and family == rsocket.AF_UNIX: + from rpython.rlib.rsocket import UNIXAddress + return UNIXAddress(space.str_w(w_address)) + if 'AF_NETLINK' in rsocket.constants and family == rsocket.AF_NETLINK: + from rpython.rlib.rsocket import NETLINKAddress + w_pid, w_groups = space.unpackiterable(w_address, 2) + return NETLINKAddress(space.uint_w(w_pid), space.uint_w(w_groups)) + raise RSocketError("unknown address family") + +# XXX Hack to seperate rpython and pypy +def make_ushort_port(space, port): + from pypy.interpreter.error import OperationError + if port < 0 or port > 0xffff: + raise OperationError(space.w_ValueError, space.wrap( + "port must be 0-65535.")) + return rffi.cast(rffi.USHORT, port) + +# XXX Hack to seperate rpython and pypy +def ipaddr_from_object(space, w_sockaddr): + host = space.str_w(space.getitem(w_sockaddr, space.wrap(0))) + addr = makeipaddr(host) + addr_fill_from_object(addr, space, w_sockaddr) + return addr + + class W_RSocket(Wrappable, RSocket): def __del__(self): self.clear_all_weakrefs() @@ -33,10 +152,19 @@ sock = rsocket.make_socket( fd, self.family, self.type, self.proto, W_RSocket) return space.newtuple([space.wrap(sock), - addr.as_object(sock.fd, space)]) + addr_as_object(addr, sock.fd, space)]) except SocketError, e: raise converted_error(space, e) + # convert an Address into an app-level object + def addr_as_object(self, space, address): + return addr_as_object(address, self.fd, space) + + # convert an app-level object into an Address + # based on the current socket's family + def addr_from_object(self, space, w_address): + return addr_from_object(self.family, space, w_address) + def bind_w(self, space, w_addr): """bind(address) @@ -104,7 +232,7 @@ """ try: addr = self.getpeername() - return addr.as_object(self.fd, space) + return addr_as_object(addr, self.fd, space) except SocketError, e: raise converted_error(space, e) @@ -116,7 +244,7 @@ """ try: addr = self.getsockname() - return addr.as_object(self.fd, space) + return addr_as_object(addr, self.fd, space) except SocketError, e: raise converted_error(space, e) @@ -194,7 +322,7 @@ try: data, addr = self.recvfrom(buffersize, flags) if addr: - w_addr = addr.as_object(self.fd, space) + w_addr = addr_as_object(addr, self.fd, space) else: w_addr = space.w_None return space.newtuple([space.wrap(data), w_addr]) @@ -319,7 +447,7 @@ try: readlgt, addr = self.recvfrom_into(rwbuffer, nbytes, flags) if addr: - w_addr = addr.as_object(self.fd, space) + w_addr = addr_as_object(addr, self.fd, space) else: w_addr = space.w_None return space.newtuple([space.wrap(readlgt), w_addr]) diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -229,13 +229,14 @@ assert space.unwrap(w_l) == info def test_unknown_addr_as_object(): + from pypy.module._socket.interp_socket import addr_as_object c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw') c_addr.c_sa_data[0] = 'c' rffi.setintfield(c_addr, 'c_sa_family', 15) # XXX what size to pass here? for the purpose of this test it has # to be short enough so we have some data, 1 sounds good enough # + sizeof USHORT - w_obj = rsocket.Address(c_addr, 1 + 2).as_object(-1, space) + w_obj = addr_as_object(rsocket.Address(c_addr, 1 + 2), t(-1, space)) assert space.is_true(space.isinstance(w_obj, space.w_tuple)) assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15 assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c' diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -112,38 +112,6 @@ """ keepalive_until_here(self) - def as_object(self, fd, space): - """Convert the address to an app-level object.""" - # If we don't know the address family, don't raise an - # exception -- return it as a tuple. - addr = self.lock() - family = rffi.cast(lltype.Signed, addr.c_sa_family) - datalen = self.addrlen - offsetof(_c.sockaddr, 'c_sa_data') - rawdata = ''.join([addr.c_sa_data[i] for i in range(datalen)]) - self.unlock() - return space.newtuple([space.wrap(family), - space.wrap(rawdata)]) - - def from_object(space, w_address): - """Convert an app-level object to an Address.""" - # It's a static method but it's overridden and must be called - # on the correct subclass. - raise RSocketError("unknown address family") - from_object = staticmethod(from_object) - - @staticmethod - def make_ushort_port(space, port): - from pypy.interpreter.error import OperationError - if port < 0 or port > 0xffff: - raise OperationError(space.w_ValueError, space.wrap( - "port must be 0-65535.")) - return rffi.cast(rffi.USHORT, port) - - def fill_from_object(self, space, w_address): - """ Purely abstract - """ - raise NotImplementedError - # ____________________________________________________________ def makeipaddr(name, result=None): @@ -268,12 +236,6 @@ self.unlock() return res - def as_object(self, fd, space): - return space.newtuple([space.wrap(self.get_ifname(fd)), - space.wrap(self.get_protocol()), - space.wrap(self.get_pkttype()), - space.wrap(self.get_hatype()), - space.wrap(self.get_addr())]) class INETAddress(IPAddress): family = AF_INET @@ -304,29 +266,6 @@ self.get_host() == other.get_host() and self.get_port() == other.get_port()) - def as_object(self, fd, space): - return space.newtuple([space.wrap(self.get_host()), - space.wrap(self.get_port())]) - - def from_object(space, w_address): - # Parse an app-level object representing an AF_INET address - w_host, w_port = space.unpackiterable(w_address, 2) - host = space.str_w(w_host) - port = space.int_w(w_port) - port = Address.make_ushort_port(space, port) - return INETAddress(host, port) - from_object = staticmethod(from_object) - - def fill_from_object(self, space, w_address): - # XXX a bit of code duplication - from pypy.interpreter.error import OperationError - _, w_port = space.unpackiterable(w_address, 2) - port = space.int_w(w_port) - port = self.make_ushort_port(space, port) - a = self.lock(_c.sockaddr_in) - rffi.setintfield(a, 'c_sin_port', htons(port)) - self.unlock() - def from_in_addr(in_addr): result = instantiate(INETAddress) # store the malloc'ed data into 'result' as soon as possible @@ -393,55 +332,6 @@ self.get_flowinfo() == other.get_flowinfo() and self.get_scope_id() == other.get_scope_id()) - def as_object(self, fd, space): - return space.newtuple([space.wrap(self.get_host()), - space.wrap(self.get_port()), - space.wrap(self.get_flowinfo()), - space.wrap(self.get_scope_id())]) - - def from_object(space, w_address): - from pypy.interpreter.error import OperationError - pieces_w = space.unpackiterable(w_address) - if not (2 <= len(pieces_w) <= 4): - raise TypeError("AF_INET6 address must be a tuple of length 2 " - "to 4, not %d" % len(pieces_w)) - host = space.str_w(pieces_w[0]) - port = space.int_w(pieces_w[1]) - port = Address.make_ushort_port(space, port) - if len(pieces_w) > 2: flowinfo = space.int_w(pieces_w[2]) - else: flowinfo = 0 - if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3]) - else: scope_id = 0 - if flowinfo < 0 or flowinfo > 0xfffff: - raise OperationError(space.w_OverflowError, space.wrap( - "flowinfo must be 0-1048575.")) - flowinfo = rffi.cast(lltype.Unsigned, flowinfo) - return INET6Address(host, port, flowinfo, scope_id) - from_object = staticmethod(from_object) - - def fill_from_object(self, space, w_address): - # XXX a bit of code duplication - from pypy.interpreter.error import OperationError - pieces_w = space.unpackiterable(w_address) - if not (2 <= len(pieces_w) <= 4): - raise RSocketError("AF_INET6 address must be a tuple of length 2 " - "to 4, not %d" % len(pieces_w)) - port = space.int_w(pieces_w[1]) - port = self.make_ushort_port(space, port) - if len(pieces_w) > 2: flowinfo = space.int_w(pieces_w[2]) - else: flowinfo = 0 - if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3]) - else: scope_id = 0 - if flowinfo < 0 or flowinfo > 0xfffff: - raise OperationError(space.w_OverflowError, space.wrap( - "flowinfo must be 0-1048575.")) - flowinfo = rffi.cast(lltype.Unsigned, flowinfo) - a = self.lock(_c.sockaddr_in6) - rffi.setintfield(a, 'c_sin6_port', htons(port)) - rffi.setintfield(a, 'c_sin6_flowinfo', htonl(flowinfo)) - rffi.setintfield(a, 'c_sin6_scope_id', scope_id) - self.unlock() - def from_in6_addr(in6_addr): result = instantiate(INET6Address) # store the malloc'ed data into 'result' as soon as possible @@ -509,13 +399,6 @@ return (isinstance(other, UNIXAddress) and self.get_path() == other.get_path()) - def as_object(self, fd, space): - return space.wrap(self.get_path()) - - def from_object(space, w_address): - return UNIXAddress(space.str_w(w_address)) - from_object = staticmethod(from_object) - if 'AF_NETLINK' in constants: class NETLINKAddress(Address): family = AF_NETLINK @@ -543,15 +426,6 @@ def __repr__(self): return '<NETLINKAddress %r>' % (self.get_pid(), self.get_groups()) - - def as_object(self, fd, space): - return space.newtuple([space.wrap(self.get_pid()), - space.wrap(self.get_groups())]) - - def from_object(space, w_address): - w_pid, w_groups = space.unpackiterable(w_address, 2) - return NETLINKAddress(space.uint_w(w_pid), space.uint_w(w_groups)) - from_object = staticmethod(from_object) # ____________________________________________________________ @@ -596,12 +470,6 @@ result.setdata(buf, 0) return result, klass.maxlen -def ipaddr_from_object(space, w_sockaddr): - host = space.str_w(space.getitem(w_sockaddr, space.wrap(0))) - addr = makeipaddr(host) - addr.fill_from_object(space, w_sockaddr) - return addr - # ____________________________________________________________ class RSocket(object): @@ -701,15 +569,6 @@ def error_handler(self): return last_error() - # convert an Address into an app-level object - def addr_as_object(self, space, address): - return address.as_object(self.fd, space) - - # convert an app-level object into an Address - # based on the current socket's family - def addr_from_object(self, space, w_address): - return af_get(self.family).from_object(space, w_address) - # build a null address object, ready to be used as output argument to # C functions that return an address. It must be unlock()ed after you # are done using addr_p. _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit