[pypy-svn] r20938 - in pypy/dist/pypy: module/_socket/rpython module/_socket/test translator/c translator/c/src translator/c/test
nik at codespeak.net
nik at codespeak.net
Fri Dec 9 15:32:16 CET 2005
Author: nik
Date: Fri Dec 9 15:32:12 2005
New Revision: 20938
Modified:
pypy/dist/pypy/module/_socket/rpython/exttable.py
pypy/dist/pypy/module/_socket/rpython/ll__socket.py
pypy/dist/pypy/module/_socket/rpython/rsocket.py
pypy/dist/pypy/module/_socket/test/test_socket2.py
pypy/dist/pypy/translator/c/extfunc.py
pypy/dist/pypy/translator/c/src/ll__socket.h
pypy/dist/pypy/translator/c/test/test_ext__socket.py
Log:
(ale, nik)
low-level implementation of socket.connect() and socket.getpeername(). intermediate
checkin for changing machines.
Modified: pypy/dist/pypy/module/_socket/rpython/exttable.py
==============================================================================
--- pypy/dist/pypy/module/_socket/rpython/exttable.py (original)
+++ pypy/dist/pypy/module/_socket/rpython/exttable.py Fri Dec 9 15:32:12 2005
@@ -5,7 +5,7 @@
import _socket
from pypy.module._socket.rpython import rsocket
from pypy.rpython.extfunctable import declare, declaretype, declareptrtype
-from pypy.rpython.extfunctable import standardexceptions
+from pypy.rpython.extfunctable import standardexceptions, noneannotation
from pypy.annotation.model import SomeTuple, SomeInteger, SomeString
from pypy.annotation import classdef
@@ -28,6 +28,9 @@
])
return addrinfo
+def ann_sockname(*args):
+ return SomeTuple([SomeString(), SomeInteger(), SomeInteger(), SomeInteger()])
+
declare(_socket.gethostname, str, '%s/gethostname' % module)
declare(_socket.gethostbyname, str, '%s/gethostbyname' % module)
@@ -42,6 +45,9 @@
declare(_socket.htonl, int, '%s/htonl' % module)
declare(rsocket.newsocket, int, '%s/newsocket' % module)
+declare(rsocket.connect, noneannotation, '%s/connect' % module)
+declare(rsocket.getpeername, ann_sockname, '%s/getpeername' % module)
+declare(rsocket.freesockname, noneannotation, '%s/freesockname' % module)
# ____________________________________________________________
# _socket.error can be raised by the above
Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py
==============================================================================
--- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original)
+++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Fri Dec 9 15:32:12 2005
@@ -34,6 +34,13 @@
('item7', Signed),
)
+SOCKNAME = GcStruct('tuple4',
+ ('item0', Ptr(STR)),
+ ('item1', Signed),
+ ('item2', Signed),
+ ('item3', Signed),
+ )
+
def ll__socket_addrinfo(family, socktype, proto, canonname,
ipaddr, port, flowinfo, scopeid):
tup = malloc(ADDRINFO_RESULT)
@@ -47,6 +54,14 @@
tup.item7 = scopeid # ipV6
return tup
+def ll__socket_sockname(host, port, flowinfo, scopeid):
+ tup = malloc(SOCKNAME)
+ tup.item0 = host
+ tup.item1 = port
+ tup.item2 = flowinfo # ipV6
+ tup.item3 = scopeid # ipV6
+ return tup
+
def ll__socket_nextaddrinfo(opaqueaddr):
addr = from_opaque_object(opaqueaddr)
return addr.nextinfo()
@@ -73,9 +88,21 @@
return _socket.ntohl(htonl)
ll__socket_ntohl.suggested_primitive = True
+# Can't actually create socket objects in these ll helpers because they are
+# turned into flowgraphs at some point, and that fails on SocketType.__init__.
+
def ll__socket_newsocket(family, type, protocol):
-# from pypy.module._socket.rpython import rsocket
-# return rsocket.newsocket(family, type, protocol).fileno()
return 0
ll__socket_newsocket.suggested_primitive = True
+def ll__socket_connect(fd, host, port):
+ return None
+ll__socket_connect.suggested_primitive = True
+
+def ll__socket_getpeername(fd):
+ return ("", 0, 0, 0)
+ll__socket_getpeername.suggested_primitive = True
+
+def ll__socket_freesockname(sockname):
+ return None
+ll__socket_freesockname.suggested_primitive = True
Modified: pypy/dist/pypy/module/_socket/rpython/rsocket.py
==============================================================================
--- pypy/dist/pypy/module/_socket/rpython/rsocket.py (original)
+++ pypy/dist/pypy/module/_socket/rpython/rsocket.py Fri Dec 9 15:32:12 2005
@@ -52,3 +52,5 @@
s = socket_cache[fd]
return s.getpeername()
+def freesockname(sockname):
+ pass
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 Fri Dec 9 15:32:12 2005
@@ -315,6 +315,8 @@
raises(TypeError, s.connect, args)
s.close()
+# XXX also need tests for other connection and timeout errors
+
class AppTestSocket:
def setup_class(cls):
Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/dist/pypy/translator/c/extfunc.py Fri Dec 9 15:32:12 2005
@@ -67,6 +67,9 @@
ll__socket.ll__socket_htonl: 'LL__socket_htonl',
ll__socket.ll__socket_ntohl: 'LL__socket_htonl',
ll__socket.ll__socket_newsocket: 'LL__socket_newsocket',
+ ll__socket.ll__socket_connect: 'LL__socket_connect',
+ ll__socket.ll__socket_getpeername: 'LL__socket_getpeername',
+ ll__socket.ll__socket_freesockname: 'LL__socket_freesockname',
}
#______________________________________________________
@@ -91,6 +94,7 @@
yield ('RPyMODF_RESULT', ll_math.MODF_RESULT)
yield ('RPySTAT_RESULT', ll_os.STAT_RESULT)
yield ('RPySOCKET_ADDRINFO', ll__socket.ADDRINFO_RESULT)
+ yield ('RPySOCKET_SOCKNAME', ll__socket.SOCKNAME)
def predeclare_utility_functions(db, rtyper):
# Common utility functions
@@ -132,6 +136,8 @@
args = [lltype.Signed, lltype.Signed, lltype.Signed, lltype.Ptr(STR),
lltype.Ptr(STR), lltype.Signed, lltype.Signed, lltype.Signed]
yield annotate(ll__socket.ll__socket_addrinfo, *args)
+ args = [lltype.Ptr(STR), lltype.Signed, lltype.Signed, lltype.Signed]
+ yield annotate(ll__socket.ll__socket_sockname, *args)
def predeclare_extfuncs(db, rtyper):
modules = {}
Modified: pypy/dist/pypy/translator/c/src/ll__socket.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll__socket.h (original)
+++ pypy/dist/pypy/translator/c/src/ll__socket.h Fri Dec 9 15:32:12 2005
@@ -77,6 +77,8 @@
return htonl(ntohl);
}
+// XXX Check what should be done threading-wise around blocking system calls
+
int LL__socket_newsocket(int family, int type, int protocol)
{
int fd;
@@ -95,6 +97,43 @@
RPYTHON_RAISE_OSERROR(errno);
}
}
+
+void LL__socket_connect(int fd, RPyString *host, int port)
+{
+ struct sockaddr_in addr;
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons((short)port);
+ if (setipaddr(RPyString_AsString(host), (struct sockaddr *) &addr,
+ sizeof(addr), AF_INET) < 0) {
+ // XXX raise some error here
+ }
+ if (connect(fd, &addr, sizeof(addr)) < 0) {
+ // XXX raise some error here
+ }
+}
+
+RPySOCKET_SOCKNAME *LL__socket_getpeername(int fd)
+{
+ struct sockaddr_in addr; // XXX IPv4 only
+ int addr_len;
+ RPySOCKET_SOCKNAME* sockname;
+ RPyString* host;
+
+ memset((void *) &addr, '\0', sizeof(addr));
+ if (getpeername(fd, (struct sockaddr *) &addr, &addr_len) < 0) {
+ // XXX raise some error
+ }
+
+ host = RPyString_FromString(inet_ntoa(addr.sin_addr));
+ return ll__socket_sockname(host, addr.sin_port, 0, 0);
+}
+
+void LL__socket_freesockname(RPySOCKET_SOCKNAME *sockname)
+{
+ free(sockname);
+}
+
/* ____________________________________________________________________________ */
/* Lock to allow python interpreter to continue, but only allow one
Modified: pypy/dist/pypy/translator/c/test/test_ext__socket.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_ext__socket.py (original)
+++ pypy/dist/pypy/translator/c/test/test_ext__socket.py Fri Dec 9 15:32:12 2005
@@ -89,3 +89,16 @@
f1 = compile(does_stuff, [int, int, int])
for args in tests:
py.test.raises(OSError, f1, *args)
+
+def test_connect():
+ from pypy.module._socket.rpython import rsocket
+ def does_stuff():
+ fd = rsocket.newsocket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
+ # XXX need to think of a test without connecting to outside servers
+ rsocket.connect(fd, "codespeak.net", 80)
+ sockname = rsocket.getpeername(fd)
+ port = sockname[1]
+ rsocket.freesockname(sockname)
+ return port
+ f1 = compile(does_stuff, [])
+ assert f1() == 80
More information about the Pypy-commit
mailing list