[pypy-svn] r18976 - in pypy/dist/pypy: module/_socket module/_socket/rpython translator/c translator/c/src translator/c/test
afa at codespeak.net
afa at codespeak.net
Wed Oct 26 00:08:01 CEST 2005
Author: afa
Date: Wed Oct 26 00:07:50 2005
New Revision: 18976
Modified:
pypy/dist/pypy/module/_socket/interp_socket.py
pypy/dist/pypy/module/_socket/rpython/exttable.py
pypy/dist/pypy/module/_socket/rpython/ll__socket.py
pypy/dist/pypy/translator/c/extfunc.py
pypy/dist/pypy/translator/c/src/ll__socket.h
pypy/dist/pypy/translator/c/test/test_extfunc.py
Log:
Some corrections for the _socket module declarations
+ added gethostbyname()
- Locking macros are commented out
- need support functions to raise exceptions correctly
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 Wed Oct 26 00:07:50 2005
@@ -6,6 +6,9 @@
from pypy.interpreter.gateway import ObjSpace, interp2app
from pypy.module._socket.rpython import rsocket
+# Force the declarations of external functions
+import pypy.module.thread.rpython.exttable
+
if sys.platform == 'win32':
WIN32_ERROR_MESSAGES = {
errno.WSAEINTR: "Interrupted system call",
@@ -768,7 +771,7 @@
method = getattr(Socket, methodname)
assert hasattr(method,'unwrap_spec'), methodname
assert method.im_func.func_code.co_argcount == len(method.unwrap_spec), methodname
- socketmethods[methodname] = interp2app(method, method.unwrap_spec)
+ socketmethods[methodname] = interp2app(method, unwrap_spec=method.unwrap_spec)
Socket.typedef = TypeDef("_socket.socket",
__doc__ = """\
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 Wed Oct 26 00:07:50 2005
@@ -4,10 +4,9 @@
import _socket
from pypy.module._socket.rpython import rsocket
-from pypy.rpython.extfunctable import declare, declareptrtype
-from pypy.annotation.model import Constant, SomeTuple, SomeList, SomeInteger, SomeString
-from pypy.annotation.listdef import ListDef
-from pypy.annotation.model import unionof
+from pypy.rpython.extfunctable import declare, declaretype, declareptrtype
+from pypy.rpython.extfunctable import standardexceptions
+from pypy.annotation.model import SomeTuple, SomeInteger, SomeString
module = 'pypy.module._socket.rpython.ll__socket'
@@ -29,6 +28,7 @@
return addrinfo
declare(_socket.gethostname, str, '%s/gethostname' % module)
+declare(_socket.gethostbyname, str, '%s/gethostbyname' % module)
declare(rsocket.getaddrinfo, rsocket.ADDRINFO, '%s/getaddrinfo' % module)
declareptrtype(rsocket.ADDRINFO, "ADDRINFO",
@@ -39,3 +39,9 @@
declare(_socket.htons, int, '%s/ntohs' % module)
declare(_socket.ntohl, int, '%s/ntohl' % module)
declare(_socket.htonl, int, '%s/htonl' % module)
+
+# ____________________________________________________________
+# _socket.error can be raised by the above
+
+# XXX a bit hackish
+standardexceptions[_socket.error] = True
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 Wed Oct 26 00:07:50 2005
@@ -10,6 +10,10 @@
return to_rstr(_socket.gethostname())
ll__socket_gethostname.suggested_primitive = True
+def ll__socket_gethostbyname(name):
+ return to_rstr(_socket.gethostbyname(name))
+ll__socket_gethostbyname.suggested_primitive = True
+
def ll__socket_getaddrinfo(host, port, family, socktype, proto, flags):
addr = rsocket.getaddrinfo(from_rstr(host), port,
family, socktype, proto, flags)
Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/dist/pypy/translator/c/extfunc.py Wed Oct 26 00:07:50 2005
@@ -58,10 +58,11 @@
ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth',
ll_stack.ll_stack_unwind: 'LL_stack_unwind',
ll_stack.ll_stack_too_big: 'LL_stack_too_big',
- ll__socket.ll__socket_gethostname: 'LL__socket_gethostname',
- ll__socket.ll__socket_getaddrinfo: 'LL__socket_getaddrinfo',
- ll__socket.ll__socket_nextaddrinfo: 'LL__socket_nextaddrinfo',
- ll__socket.ll__socket_freeaddrinfo: 'LL__socket_freeaddrinfo',
+ ll__socket.ll__socket_gethostname: 'LL__socket_gethostname',
+ ll__socket.ll__socket_gethostbyname: 'LL__socket_gethostbyname',
+ ll__socket.ll__socket_getaddrinfo: 'LL__socket_getaddrinfo',
+ ll__socket.ll__socket_nextaddrinfo: 'LL__socket_nextaddrinfo',
+ ll__socket.ll__socket_freeaddrinfo: 'LL__socket_freeaddrinfo',
ll__socket.ll__socket_ntohs: 'LL__socket_ntohs',
ll__socket.ll__socket_htons: 'LL__socket_htons',
ll__socket.ll__socket_htonl: 'LL__socket_htonl',
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 Wed Oct 26 00:07:50 2005
@@ -13,6 +13,7 @@
long LL__socket_ntohl(long htonl);
long LL__socket_htonl(long ntohl);
RPyString *LL__socket_gethostname(void);
+RPyString *LL__socket_gethostbyname(RPyString *name);
struct RPyOpaque_ADDRINFO *LL__socket_getaddrinfo(RPyString *host, RPyString *port,
int family, int socktype,
int proto, int flags);
@@ -73,15 +74,181 @@
return htonl(ntohl);
}
+/* ____________________________________________________________________________ */
+
+/* Lock to allow python interpreter to continue, but only allow one
+ thread to be in gethostbyname or getaddrinfo */
+#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+/* XXX */
+/* RPyThread_type_lock netdb_lock; */
+#endif
+
+#ifdef USE_GETADDRINFO_LOCK
+/* XXX not used */
+/* #define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1); */
+/* #define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock); */
+#else
+/* #define ACQUIRE_GETADDRINFO_LOCK */
+/* #define RELEASE_GETADDRINFO_LOCK */
+#endif
+
+
+/* Convert a string specifying a host name or one of a few symbolic
+ names to a numeric IP address. This usually calls gethostbyname()
+ to do the work; the names "" and "<broadcast>" are special.
+ Return the length (IPv4 should be 4 bytes), or negative if
+ an error occurred; then an exception is raised. */
+
+static int
+setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af)
+{
+ struct addrinfo hints, *res;
+ int error;
+ int d1, d2, d3, d4;
+ char ch;
+
+ memset((void *) addr_ret, '\0', sizeof(*addr_ret));
+ if (name[0] == '\0') {
+ int siz;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_PASSIVE;
+ /* XXX Py_BEGIN_ALLOW_THREADS */
+ /* XXX ACQUIRE_GETADDRINFO_LOCK */
+ error = getaddrinfo(NULL, "0", &hints, &res);
+ /* XXX Py_END_ALLOW_THREADS */
+ /* We assume that those thread-unsafe getaddrinfo() versions
+ *are* safe regarding their return value, ie. that a
+ subsequent call to getaddrinfo() does not destroy the
+ outcome of the first call. */
+ /* XXX RELEASE_GETADDRINFO_LOCK */
+ if (error) {
+ RPYTHON_RAISE_OSERROR(errno); /* XXX set_gaierror(error);*/
+ return -1;
+ }
+ switch (res->ai_family) {
+ case AF_INET:
+ siz = 4;
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ siz = 16;
+ break;
+#endif
+ default:
+ freeaddrinfo(res);
+ RPyRaiseSimpleException(PyExc_socket_error,
+ "unsupported address family");
+ return -1;
+ }
+ if (res->ai_next) {
+ freeaddrinfo(res);
+ RPyRaiseSimpleException(PyExc_socket_error,
+ "wildcard resolved to multiple address");
+ return -1;
+ }
+ if (res->ai_addrlen < addr_ret_size)
+ addr_ret_size = res->ai_addrlen;
+ memcpy(addr_ret, res->ai_addr, addr_ret_size);
+ freeaddrinfo(res);
+ return siz;
+ }
+ if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
+ struct sockaddr_in *sin;
+ if (af != AF_INET && af != AF_UNSPEC) {
+ RPyRaiseSimpleException(PyExc_socket_error,
+ "address family mismatched");
+ return -1;
+ }
+ sin = (struct sockaddr_in *)addr_ret;
+ memset((void *) sin, '\0', sizeof(*sin));
+ sin->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(*sin);
+#endif
+ sin->sin_addr.s_addr = INADDR_BROADCAST;
+ return sizeof(sin->sin_addr);
+ }
+ if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
+ 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
+ 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
+ struct sockaddr_in *sin;
+ sin = (struct sockaddr_in *)addr_ret;
+ sin->sin_addr.s_addr = htonl(
+ ((long) d1 << 24) | ((long) d2 << 16) |
+ ((long) d3 << 8) | ((long) d4 << 0));
+ sin->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(*sin);
+#endif
+ return 4;
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ /* XXX Py_BEGIN_ALLOW_THREADS */
+ /* XXX ACQUIRE_GETADDRINFO_LOCK */
+ error = getaddrinfo(name, NULL, &hints, &res);
+#if defined(__digital__) && defined(__unix__)
+ if (error == EAI_NONAME && af == AF_UNSPEC) {
+ /* On Tru64 V5.1, numeric-to-addr conversion fails
+ if no address family is given. Assume IPv4 for now.*/
+ hints.ai_family = AF_INET;
+ error = getaddrinfo(name, NULL, &hints, &res);
+ }
+#endif
+ /* XXX Py_END_ALLOW_THREADS */
+ /* XXX RELEASE_GETADDRINFO_LOCK */ /* see comment in setipaddr() */
+ if (error) {
+ RPYTHON_RAISE_OSERROR(errno); /* XXX set_gaierror(error); */
+ return -1;
+ }
+ if (res->ai_addrlen < addr_ret_size)
+ addr_ret_size = res->ai_addrlen;
+ memcpy((char *) addr_ret, res->ai_addr, addr_ret_size);
+ freeaddrinfo(res);
+ switch (addr_ret->sa_family) {
+ case AF_INET:
+ return 4;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ return 16;
+#endif
+ default:
+ RPyRaiseSimpleException(PyExc_socket_error,
+ "unknown address family");
+ return -1;
+ }
+}
+
+
+/* Create a string object representing an IP address.
+ This is always a string of the form 'dd.dd.dd.dd' (with variable
+ size numbers). */
+
+RPyString *makeipaddr(struct sockaddr *addr, int addrlen)
+{
+ char buf[NI_MAXHOST];
+ int error;
+
+ error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
+ NI_NUMERICHOST);
+ if (error) {
+ return RPyString_FromString("socket.gaierror"); // XXX
+ }
+ return RPyString_FromString(buf);
+}
+
+/* ____________________________________________________________________________ */
+
RPyString *LL__socket_gethostname(void)
{
char buf[1024];
int res;
res = gethostname(buf, sizeof buf - 1);
if (res < 0) {
- //XXX
- //RPYTHON_RAISE_OSERROR(errno);
- RPyRaiseSimpleException(PyExc_ValueError,
+ /* XXX set_error(); */
+ RPyRaiseSimpleException(PyExc_socket_error,
"gethostname() error");
return NULL;
}
@@ -117,17 +284,18 @@
return addr;
}
-RPyString *makeipaddr(struct sockaddr *addr)
+RPyString *LL__socket_gethostbyname(RPyString *name)
{
- char buf[NI_MAXHOST];
- int error;
-
- error = getnameinfo(addr, sizeof (struct sockaddr), buf, sizeof(buf), NULL, 0,
- NI_NUMERICHOST);
- if (error) {
- return RPyString_FromString("Error"); // XXX
- }
- return RPyString_FromString(buf);
+#ifdef ENABLE_IPV6
+ struct sockaddr_storage addrbuf;
+#else
+ struct sockaddr_in addrbuf;
+#endif
+ if (setipaddr(RPyString_AsString(name), (struct sockaddr *)&addrbuf,
+ sizeof(addrbuf), AF_INET) < 0)
+ return NULL;
+ return makeipaddr((struct sockaddr *)&addrbuf,
+ sizeof(struct sockaddr_in));
}
RPySOCKET_ADDRINFO *LL__socket_nextaddrinfo(struct RPyOpaque_ADDRINFO *addr)
@@ -145,7 +313,8 @@
RPyString *canonname = RPyString_FromString(
info->ai_canonname?info->ai_canonname:"");
- RPyString *ipaddr = makeipaddr(info->ai_addr);
+ RPyString *ipaddr = makeipaddr(info->ai_addr,
+ sizeof(struct sockaddr_in));
ret = ll__socket_addrinfo(info->ai_family,
info->ai_socktype,
Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_extfunc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_extfunc.py Wed Oct 26 00:07:50 2005
@@ -562,6 +562,15 @@
res = f1()
assert res == _socket.gethostname()
+
+def test_gethostbyname():
+ import pypy.module._socket.rpython.exttable # for declare()/declaretype()
+ def does_stuff(host):
+ return _socket.gethostbyname(host)
+ f1 = compile(does_stuff, [str])
+ res = f1("localhost")
+ assert res == _socket.gethostbyname("localhost")
+
def test_getaddrinfo():
import pypy.module._socket.rpython.exttable # for declare()/declaretype()
from pypy.module._socket.rpython import rsocket
@@ -579,4 +588,3 @@
f1 = compile(does_stuff, [str, str])
res = f1("localhost", "25")
assert eval(res) == _socket.getaddrinfo("localhost", "25")
-
More information about the Pypy-commit
mailing list