summaryrefslogtreecommitdiffstats
path: root/Modules/socketmodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1995-01-02 19:30:30 (GMT)
committerGuido van Rossum <guido@python.org>1995-01-02 19:30:30 (GMT)
commit3bbc62e9c25d4c006cd21d6b1314ccf0ba211382 (patch)
tree0b1a6d87c3bd250a62235f9df6ed9fffddbbabae /Modules/socketmodule.c
parent437a0e60baa6eabc2c853bee7ce1543481db8ca7 (diff)
downloadcpython-3bbc62e9c25d4c006cd21d6b1314ccf0ba211382.zip
cpython-3bbc62e9c25d4c006cd21d6b1314ccf0ba211382.tar.gz
cpython-3bbc62e9c25d4c006cd21d6b1314ccf0ba211382.tar.bz2
Another bulky set of minor changes.
Note addition of gethostbyaddr() and improved repr() for sockets, renaming of md5.md5() to md5.new(), and fixing of leaks in threads.
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r--Modules/socketmodule.c154
1 files changed, 131 insertions, 23 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index bda7bf1..39aa81e 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -38,6 +38,7 @@ Interface:
- socket.gethostname() --> host name (string)
- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd')
+- socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...])
- socket.getservbyname(servername, protocolname) --> port number
- socket.socket(family, type [, proto]) --> new socket object
- family and type constants from <socket.h> are accessed as socket.AF_INET etc.
@@ -66,6 +67,7 @@ Socket methods:
- s.setblocking(1 | 0) --> Py_None
- s.shutdown(how) --> Py_None
- s.close() --> Py_None
+- repr(s) --> "<socket object, fd=%d, family=%d, type=%d, protocol=%d>"
*/
@@ -89,6 +91,11 @@ Socket methods:
#undef AF_UNIX
#endif
+#ifndef O_NDELAY
+#define O_NDELAY O_NONBLOCK /* For QNX only? */
+#endif
+
+
/* Here we have some hacks to choose between K&R or ANSI style function
definitions. For NT to build this as an extension module (ie, DLL)
it must be compiled by the C++ compiler, as it takes the address of
@@ -177,6 +184,12 @@ typedef struct {
int sock_family; /* Address family, e.g., AF_INET */
int sock_type; /* Socket type, e.g., SOCK_STREAM */
int sock_proto; /* Protocol type, usually 0 */
+ union sock_addr {
+ struct sockaddr_in in;
+#ifdef AF_UNIX
+ struct sockaddr_un un;
+#endif
+ } sock_addr;
} PySocketSockObject;
@@ -194,7 +207,7 @@ staticforward PyTypeObject PySocketSock_Type;
in NEWOBJ()). */
static PySocketSockObject *
-BUILD_FUNC_DEF_4(PySocketSock_New, int, fd, int, family, int, type, int, proto)
+BUILD_FUNC_DEF_4(PySocketSock_New,int,fd, int,family, int,type, int,proto)
{
PySocketSockObject *s;
s = PyObject_NEW(PySocketSockObject, &PySocketSock_Type);
@@ -215,11 +228,17 @@ BUILD_FUNC_DEF_4(PySocketSock_New, int, fd, int, family, int, type, int, proto)
an error occurred; then an exception is raised. */
static int
-BUILD_FUNC_DEF_2(setipaddr, char*, name, struct sockaddr_in *, addr_ret)
+BUILD_FUNC_DEF_2(setipaddr, char*,name, struct sockaddr_in *,addr_ret)
{
struct hostent *hp;
int d1, d2, d3, d4;
char ch;
+#ifdef HAVE_GETHOSTBYNAME_R
+ struct hostent hp_allocated;
+ char buf[1001];
+ int buf_len = (sizeof buf) - 1;
+ int errnop;
+#endif /* HAVE_GETHOSTBYNAME_R */
if (name[0] == '\0') {
addr_ret->sin_addr.s_addr = INADDR_ANY;
@@ -237,11 +256,22 @@ BUILD_FUNC_DEF_2(setipaddr, char*, name, struct sockaddr_in *, addr_ret)
((long) d3 << 8) | ((long) d4 << 0));
return 4;
}
+#ifdef HAVE_GETHOSTBYNAME_R
Py_BEGIN_ALLOW_THREADS
- hp = gethostbyname(name);
+ hp = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop);
Py_END_ALLOW_THREADS
+#else /* not HAVE_GETHOSTBYNAME_R */
+ hp = gethostbyname(name);
+#endif /* HAVE_GETHOSTBYNAME_R */
+
if (hp == NULL) {
+#ifndef NT
+ /* Let's get real error message to return */
+ extern int h_errno;
+ PyErr_SetString(PySocket_Error, (char *)hstrerror(h_errno));
+#else
PyErr_SetString(PySocket_Error, "host not found");
+#endif
return -1;
}
memcpy((char *) &addr_ret->sin_addr, hp->h_addr, hp->h_length);
@@ -272,7 +302,7 @@ BUILD_FUNC_DEF_1(makeipaddr, struct sockaddr_in *,addr)
/*ARGSUSED*/
static PyObject *
-BUILD_FUNC_DEF_2(makesockaddr,struct sockaddr *, addr, int, addrlen)
+BUILD_FUNC_DEF_2(makesockaddr,struct sockaddr *,addr, int,addrlen)
{
if (addrlen == 0) {
/* No address -- may be recvfrom() from known socket */
@@ -323,36 +353,38 @@ getsockaddrarg,PySocketSockObject *,s, PyObject *,args, struct sockaddr **,addr_
#ifdef AF_UNIX
case AF_UNIX:
{
- static struct sockaddr_un addr;
+ struct sockaddr_un* addr;
char *path;
int len;
+ addr = (struct sockaddr_un* )&(s->sock_addr).un;
if (!PyArg_Parse(args, "s#", &path, &len))
return 0;
- if (len > sizeof addr.sun_path) {
+ if (len > sizeof addr->sun_path) {
PyErr_SetString(PySocket_Error, "AF_UNIX path too long");
return 0;
}
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, path, len);
- *addr_ret = (struct sockaddr *) &addr;
- *len_ret = len + sizeof addr.sun_family;
+ addr->sun_family = AF_UNIX;
+ memcpy(addr->sun_path, path, len);
+ *addr_ret = (struct sockaddr *) addr;
+ *len_ret = len + sizeof addr->sun_family;
return 1;
}
#endif /* AF_UNIX */
case AF_INET:
{
- static struct sockaddr_in addr;
+ struct sockaddr_in* addr;
char *host;
int port;
+ addr=(struct sockaddr_in*)&(s->sock_addr).in;
if (!PyArg_Parse(args, "(si)", &host, &port))
return 0;
- if (setipaddr(host, &addr) < 0)
+ if (setipaddr(host, addr) < 0)
return 0;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- *addr_ret = (struct sockaddr *) &addr;
- *len_ret = sizeof addr;
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(port);
+ *addr_ret = (struct sockaddr *) addr;
+ *len_ret = sizeof *addr;
return 1;
}
@@ -764,7 +796,7 @@ BUILD_FUNC_DEF_2(PySocketSock_recvfrom,PySocketSockObject *,s, PyObject *,args)
#ifndef NT
(ANY *)addrbuf, &addrlen);
#else
- (struct sockaddr *)addrbuf, &addrlen);
+ (struct sockaddr *)addrbuf, &addrlen);
#endif
Py_END_ALLOW_THREADS
if (n < 0)
@@ -854,7 +886,7 @@ static PyMethodDef PySocketSock_methods[] = {
{"allowbroadcast", (PyCFunction)PySocketSock_allowbroadcast},
#endif
#ifndef NT
- {"setblocking", (PyCFunction)PySocketSock_setblocking},
+ {"setblocking", (PyCFunction)PySocketSock_setblocking},
#endif
{"setsockopt", (PyCFunction)PySocketSock_setsockopt},
{"getsockopt", (PyCFunction)PySocketSock_getsockopt},
@@ -883,7 +915,7 @@ static PyMethodDef PySocketSock_methods[] = {
First close the file description. */
static void
-BUILD_FUNC_DEF_1(PySocketSock_dealloc, PySocketSockObject *,s)
+BUILD_FUNC_DEF_1(PySocketSock_dealloc,PySocketSockObject *,s)
{
(void) close(s->sock_fd);
PyMem_DEL(s);
@@ -899,6 +931,22 @@ BUILD_FUNC_DEF_2(PySocketSock_getattr,PySocketSockObject *,s, char *,name)
}
+static PyObject *
+BUILD_FUNC_DEF_1(PySocketSock_repr,PySocketSockObject *,s)
+{
+ PyObject *addro;
+ struct sockaddr *addr;
+ char buf[512];
+ object *t, *comma, *v;
+ int i, len;
+ sprintf(buf,
+ "<socket object, fd=%d, family=%d, type=%d, protocol=%d>",
+ s->sock_fd, s->sock_family, s->sock_type, s->sock_proto);
+ t = newstringobject(buf);
+ return t;
+}
+
+
/* Type object for socket objects. */
static PyTypeObject PySocketSock_Type = {
@@ -912,7 +960,7 @@ static PyTypeObject PySocketSock_Type = {
(getattrfunc)PySocketSock_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
- 0, /*tp_repr*/
+ (reprfunc)PySocketSock_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
@@ -954,6 +1002,65 @@ BUILD_FUNC_DEF_2(PySocket_gethostbyname,PyObject *,self, PyObject *,args)
return makeipaddr(&addrbuf);
}
+/* Python interface to gethostbyaddr(IP). */
+
+/*ARGSUSED*/
+static PyObject *
+BUILD_FUNC_DEF_2(PySocket_gethostbyaddr,PyObject *,self, PyObject *, args)
+{
+ struct sockaddr_in addr;
+ char *ip_num;
+ struct hostent *h;
+ int d1,d2,d3,d4;
+ char ch, **pch;
+ PyObject *rtn_tuple = (PyObject *)NULL;
+ PyObject *name_list = (PyObject *)NULL;
+ PyObject *addr_list = (PyObject *)NULL;
+ PyObject *tmp;
+
+ if (!PyArg_Parse(args, "s", &ip_num))
+ return NULL;
+ if (setipaddr(ip_num, &addr) < 0)
+ return NULL;
+ h = gethostbyaddr((char *)&addr.sin_addr,
+ sizeof(addr.sin_addr),
+ AF_INET);
+ if (h == NULL) {
+#ifndef NT
+ /* Let's get real error message to return */
+ extern int h_errno;
+ PyErr_SetString(PySocket_Error, (char *)hstrerror(h_errno));
+#else
+ PyErr_SetString(PySocket_Error, "host not found");
+#endif
+ return NULL;
+ }
+ if ((name_list = PyList_New(0)) == NULL)
+ goto err;
+ if ((addr_list = PyList_New(0)) == NULL)
+ goto err;
+ for (pch = h->h_aliases; *pch != NULL; pch++) {
+ tmp = PyString_FromString(*pch);
+ if (tmp == NULL)
+ goto err;
+ PyList_Append(name_list, tmp);
+ Py_DECREF(tmp);
+ }
+ for (pch = h->h_addr_list; *pch != NULL; pch++) {
+ memcpy((char *) &addr.sin_addr, *pch, h->h_length);
+ tmp = makeipaddr(&addr);
+ if (tmp == NULL)
+ goto err;
+ PyList_Append(addr_list, tmp);
+ Py_DECREF(tmp);
+ }
+ rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
+ err:
+ Py_XDECREF(name_list);
+ Py_XDECREF(addr_list);
+ return rtn_tuple;
+}
+
/* Python interface to getservbyname(name).
This only returns the port number, since the other info is already
@@ -984,7 +1091,7 @@ BUILD_FUNC_DEF_2(PySocket_getservbyname,PyObject *,self, PyObject *,args)
/*ARGSUSED*/
static PyObject *
-BUILD_FUNC_DEF_2(PySocket_socket,PyObject *,self,PyObject *,args)
+BUILD_FUNC_DEF_2(PySocket_socket,PyObject *,self, PyObject *,args)
{
PySocketSockObject *s;
int fd, family, type, proto;
@@ -1019,7 +1126,7 @@ BUILD_FUNC_DEF_2(PySocket_socket,PyObject *,self,PyObject *,args)
/*ARGSUSED*/
static PyObject *
-BUILD_FUNC_DEF_2(PySocket_fromfd,PyObject *,self,PyObject *,args)
+BUILD_FUNC_DEF_2(PySocket_fromfd,PyObject *,self, PyObject *,args)
{
PySocketSockObject *s;
int fd, family, type, proto;
@@ -1047,6 +1154,7 @@ BUILD_FUNC_DEF_2(PySocket_fromfd,PyObject *,self,PyObject *,args)
static PyMethodDef PySocket_methods[] = {
{"gethostbyname", PySocket_gethostbyname},
+ {"gethostbyaddr", PySocket_gethostbyaddr},
{"gethostname", PySocket_gethostname},
{"getservbyname", PySocket_getservbyname},
{"socket", PySocket_socket},
@@ -1061,7 +1169,7 @@ static PyMethodDef PySocket_methods[] = {
For simplicity, errors (which are unlikely anyway) are ignored. */
static void
-BUILD_FUNC_DEF_3(insint,PyObject *,d,char *,name,int,value)
+BUILD_FUNC_DEF_3(insint,PyObject *,d, char *,name, int,value)
{
PyObject *v = PyInt_FromLong((long) value);
if (v == NULL) {