[Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.188,1.189
Guido van Rossum
gvanrossum@users.sourceforge.net
Sat, 27 Oct 2001 15:20:49 -0700
Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv18477
Modified Files:
socketmodule.c
Log Message:
Made SocketType and socket the same thing: a subclassable type whose
constructor acts just like socket() before. All three arguments have
a sensible default now; socket() is equivalent to
socket(AF_INET, SOCK_STREAM).
One minor issue: the socket() function and the SocketType had
different doc strings; socket.__doc__ gave the signature,
SocketType.__doc__ gave the methods. I've merged these for now, but
maybe the list of methods is no longer necessary since it can easily
be recovered through socket.__dict__.keys(). The problem with keeping
it is that the total doc string is a bit long (34 lines -- it scrolls
of a standard tty screen).
Another general issue with the socket module is that it's a big mess.
There's pages and pages of random platform #ifdefs, and the naming
conventions are totally wrong: it uses Py prefixes and CapWords for
static functions. That's a cleanup for another day... (Also I think
the big starting comment that summarizes the API can go -- it's a
repeat of the docstring.)
Index: socketmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v
retrieving revision 1.188
retrieving revision 1.189
diff -C2 -d -r1.188 -r1.189
*** socketmodule.c 2001/10/26 03:25:00 1.188
--- socketmodule.c 2001/10/27 22:20:47 1.189
***************
*** 10,15 ****
- only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
portable manner, though AF_PACKET is supported under Linux.
! - no read/write operations (use send/recv or makefile instead)
! - additional restrictions apply on Windows
Module interface:
--- 10,15 ----
- only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
portable manner, though AF_PACKET is supported under Linux.
! - no read/write operations (use sendall/recv or makefile instead)
! - additional restrictions apply on Windows (compensated for by socket.py)
Module interface:
***************
*** 78,81 ****
--- 78,84 ----
#include "Python.h"
+ /* XXX This is a terrible mess of of platform-dependent preprocessor hacks.
+ I hope some day someone can clean this up please... */
+
/* Hacks for gethostbyname_r(). On some non-Linux platforms, the configure
script doesn't get this right, so we hardcode some platform checks below.
***************
*** 268,271 ****
--- 271,278 ----
#endif
+
+ /* XXX There's a problem here: *static* functions are not supposed to have
+ a Py prefix (or use CapitalizedWords). Later... */
+
/* Global variable holding the exception type for errors detected
by this module (but not argument type or memory errors, etc.). */
***************
*** 461,465 ****
typedef struct {
PyObject_HEAD
! SOCKET_T sock_fd; /* Socket file descriptor */
int sock_family; /* Address family, e.g., AF_INET */
int sock_type; /* Socket type, e.g., SOCK_STREAM */
--- 468,472 ----
typedef struct {
PyObject_HEAD
! SOCKET_T sock_fd; /* Socket file descriptor */
int sock_family; /* Address family, e.g., AF_INET */
int sock_type; /* Socket type, e.g., SOCK_STREAM */
***************
*** 512,515 ****
--- 519,543 ----
+ /* Initialize a new socket object. */
+
+ static void
+ init_sockobject(PySocketSockObject *s,
+ SOCKET_T fd, int family, int type, int proto)
+ {
+ #ifdef RISCOS
+ int block = 1;
+ #endif
+ s->sock_fd = fd;
+ s->sock_family = family;
+ s->sock_type = type;
+ s->sock_proto = proto;
+ #ifdef RISCOS
+ if(taskwindow) {
+ socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
+ }
+ #endif
+ }
+
+
/* Create a new socket object.
This just creates the object and initializes it.
***************
*** 520,540 ****
PySocketSock_New(SOCKET_T fd, int family, int type, int proto)
{
- #ifdef RISCOS
- int block = 1;
- #endif
PySocketSockObject *s;
! PySocketSock_Type.ob_type = &PyType_Type;
! s = PyObject_New(PySocketSockObject, &PySocketSock_Type);
! if (s != NULL) {
! s->sock_fd = fd;
! s->sock_family = family;
! s->sock_type = type;
! s->sock_proto = proto;
! #ifdef RISCOS
! if(taskwindow) {
! socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
! }
! #endif
! }
return s;
}
--- 548,556 ----
PySocketSock_New(SOCKET_T fd, int family, int type, int proto)
{
PySocketSockObject *s;
! s = (PySocketSockObject *)
! PyType_GenericNew(&PySocketSock_Type, NULL, NULL);
! if (s != NULL)
! init_sockobject(s, fd, family, type, proto);
return s;
}
***************
*** 1721,1734 ****
if (s->sock_fd != -1)
(void) SOCKETCLOSE(s->sock_fd);
! PyObject_Del(s);
! }
!
!
! /* Return a socket object's named attribute. */
!
! static PyObject *
! PySocketSock_getattr(PySocketSockObject *s, char *name)
! {
! return Py_FindMethod(PySocketSock_methods, (PyObject *) s, name);
}
--- 1737,1741 ----
if (s->sock_fd != -1)
(void) SOCKETCLOSE(s->sock_fd);
! s->ob_type->tp_free((PyObject *)s);
}
***************
*** 1755,1775 ****
/* Type object for socket objects. */
static PyTypeObject PySocketSock_Type = {
PyObject_HEAD_INIT(0) /* Must fill in type value later */
! 0,
! "socket",
! sizeof(PySocketSockObject),
! 0,
! (destructor)PySocketSock_dealloc, /*tp_dealloc*/
! 0, /*tp_print*/
! (getattrfunc)PySocketSock_getattr, /*tp_getattr*/
! 0, /*tp_setattr*/
! 0, /*tp_compare*/
! (reprfunc)PySocketSock_repr, /*tp_repr*/
! 0, /*tp_as_number*/
! 0, /*tp_as_sequence*/
! 0, /*tp_as_mapping*/
};
--- 1762,1895 ----
+ /* Create a new, uninitialized socket object. */
+
+ static PyObject *
+ PySocketSock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ PyObject *new;
+
+ new = type->tp_alloc(type, 0);
+ if (new != NULL)
+ ((PySocketSockObject *)new)->sock_fd = -1;
+ return new;
+ }
+
+
+ /* Initialize a new socket object. */
+
+ /*ARGSUSED*/
+ static int
+ PySocketSock_init(PyObject *self, PyObject *args, PyObject *kwds)
+ {
+ PySocketSockObject *s = (PySocketSockObject *)self;
+ SOCKET_T fd;
+ int family = AF_INET, type = SOCK_STREAM, proto = 0;
+ static char *keywords[] = {"family", "type", "proto", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "|iii:socket", keywords,
+ &family, &type, &proto))
+ return -1;
+ Py_BEGIN_ALLOW_THREADS
+ fd = socket(family, type, proto);
+ Py_END_ALLOW_THREADS
+ #ifdef MS_WINDOWS
+ if (fd == INVALID_SOCKET)
+ #else
+ if (fd < 0)
+ #endif
+ {
+ PySocket_Err();
+ return -1;
+ }
+ init_sockobject(s, fd, family, type, proto);
+ /* From now on, ignore SIGPIPE and let the error checking
+ do the work. */
+ #ifdef SIGPIPE
+ (void) signal(SIGPIPE, SIG_IGN);
+ #endif
+ return 0;
+ }
+
+
/* Type object for socket objects. */
+ static char socket_doc[] =
+ "socket([family[, type[, proto]]]) -> socket object\n\
+ \n\
+ Open a socket of the given type. The family argument specifies the\n\
+ address family; it defaults to AF_INET. The type argument specifies\n\
+ whether this is a stream (SOCK_STREAM, this is the default)\n\
+ or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\
+ specifying the default protocol.\n\
+ \n\
+ A socket represents one endpoint of a network connection.\n\
+ \n\
+ Methods:\n\
+ \n\
+ accept() -- accept a connection, returning new socket and client address\n\
+ bind() -- bind the socket to a local address\n\
+ close() -- close the socket\n\
+ connect() -- connect the socket to a remote address\n\
+ connect_ex() -- connect, return an error code instead of an exception \n\
+ dup() -- return a new socket object identical to the current one (*)\n\
+ fileno() -- return underlying file descriptor\n\
+ getpeername() -- return remote address (*)\n\
+ getsockname() -- return local address\n\
+ getsockopt() -- get socket options\n\
+ listen() -- start listening for incoming connections\n\
+ makefile() -- return a file object corresponding tot the socket (*)\n\
+ recv() -- receive data\n\
+ recvfrom() -- receive data and sender's address\n\
+ send() -- send data, may not send all of it\n\
+ sendall() -- send all data\n\
+ sendto() -- send data to a given address\n\
+ setblocking() -- set or clear the blocking I/O flag\n\
+ setsockopt() -- set socket options\n\
+ shutdown() -- shut down traffic in one or both directions\n\
+ \n\
+ (*) not available on all platforms!)";
+
static PyTypeObject PySocketSock_Type = {
PyObject_HEAD_INIT(0) /* Must fill in type value later */
! 0, /* ob_size */
! "socket.socket", /* tp_name */
! sizeof(PySocketSockObject), /* tp_basicsize */
! 0, /* tp_itemsize */
! (destructor)PySocketSock_dealloc, /* tp_dealloc */
! 0, /* tp_print */
! 0, /* tp_getattr */
! 0, /* tp_setattr */
! 0, /* tp_compare */
! (reprfunc)PySocketSock_repr, /* tp_repr */
! 0, /* tp_as_number */
! 0, /* tp_as_sequence */
! 0, /* tp_as_mapping */
! 0, /* tp_hash */
! 0, /* tp_call */
! 0, /* tp_str */
! PyObject_GenericGetAttr, /* tp_getattro */
! 0, /* tp_setattro */
! 0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
! socket_doc, /* tp_doc */
! 0, /* tp_traverse */
! 0, /* tp_clear */
! 0, /* tp_richcompare */
! 0, /* tp_weaklistoffset */
! 0, /* tp_iter */
! 0, /* tp_iternext */
! PySocketSock_methods, /* tp_methods */
! 0, /* tp_members */
! 0, /* tp_getset */
! 0, /* tp_base */
! 0, /* tp_dict */
! 0, /* tp_descr_get */
! 0, /* tp_descr_set */
! 0, /* tp_dictoffset */
! PySocketSock_init, /* tp_init */
! PyType_GenericAlloc, /* tp_alloc */
! PySocketSock_new, /* tp_new */
! _PyObject_Del, /* tp_free */
};
***************
*** 2150,2198 ****
- /* Python interface to socket(family, type, proto).
- The third (protocol) argument is optional.
- Return a new socket object. */
-
- /*ARGSUSED*/
- static PyObject *
- PySocket_socket(PyObject *self, PyObject *args)
- {
- PySocketSockObject *s;
- SOCKET_T fd;
- int family, type, proto = 0;
- if (!PyArg_ParseTuple(args, "ii|i:socket", &family, &type, &proto))
- return NULL;
- Py_BEGIN_ALLOW_THREADS
- fd = socket(family, type, proto);
- Py_END_ALLOW_THREADS
- #ifdef MS_WINDOWS
- if (fd == INVALID_SOCKET)
- #else
- if (fd < 0)
- #endif
- return PySocket_Err();
- s = PySocketSock_New(fd, family, type, proto);
- /* If the object can't be created, don't forget to close the
- file descriptor again! */
- if (s == NULL)
- (void) SOCKETCLOSE(fd);
- /* From now on, ignore SIGPIPE and let the error checking
- do the work. */
- #ifdef SIGPIPE
- (void) signal(SIGPIPE, SIG_IGN);
- #endif
- return (PyObject *) s;
- }
-
- static char socket_doc[] =
- "socket(family, type[, proto]) -> socket object\n\
- \n\
- Open a socket of the given type. The family argument specifies the\n\
- address family; it is normally AF_INET, sometimes AF_UNIX.\n\
- The type argument specifies whether this is a stream (SOCK_STREAM)\n\
- or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\
- specifying the default protocol.";
-
-
#ifndef NO_DUP
/* Create a socket object from a numeric file description.
--- 2270,2273 ----
***************
*** 2793,2797 ****
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
! "SSL", /*tp_name*/
sizeof(PySSLObject), /*tp_basicsize*/
0, /*tp_itemsize*/
--- 2868,2872 ----
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
! "SSL", /*tp_name*/
sizeof(PySSLObject), /*tp_basicsize*/
0, /*tp_itemsize*/
***************
*** 2887,2892 ****
{"getprotobyname", PySocket_getprotobyname,
METH_VARARGS,getprotobyname_doc},
- {"socket", PySocket_socket,
- METH_VARARGS, socket_doc},
#ifndef NO_DUP
{"fromfd", PySocket_fromfd,
--- 2962,2965 ----
***************
*** 3030,3060 ****
for documentation.";
- static char sockettype_doc[] =
- "A socket represents one endpoint of a network connection.\n\
- \n\
- Methods:\n\
- \n\
- accept() -- accept a connection, returning new socket and client address\n\
- bind() -- bind the socket to a local address\n\
- close() -- close the socket\n\
- connect() -- connect the socket to a remote address\n\
- connect_ex() -- connect, return an error code instead of an exception \n\
- dup() -- return a new socket object identical to the current one (*)\n\
- fileno() -- return underlying file descriptor\n\
- getpeername() -- return remote address (*)\n\
- getsockname() -- return local address\n\
- getsockopt() -- get socket options\n\
- listen() -- start listening for incoming connections\n\
- makefile() -- return a file object corresponding tot the socket (*)\n\
- recv() -- receive data\n\
- recvfrom() -- receive data and sender's address\n\
- send() -- send data\n\
- sendto() -- send data to a given address\n\
- setblocking() -- set or clear the blocking I/O flag\n\
- setsockopt() -- set socket options\n\
- shutdown() -- shut down traffic in one or both directions\n\
- \n\
- (*) not available on all platforms!)";
-
DL_EXPORT(void)
init_socket(void)
--- 3103,3106 ----
***************
*** 3077,3080 ****
--- 3123,3127 ----
#endif /* MS_WINDOWS */
#endif /* RISCOS */
+ PySocketSock_Type.ob_type = &PyType_Type;
#ifdef USE_SSL
PySSL_Type.ob_type = &PyType_Type;
***************
*** 3118,3124 ****
SSL_ERROR_SSL);
#endif /* USE_SSL */
- PySocketSock_Type.ob_type = &PyType_Type;
- PySocketSock_Type.tp_doc = sockettype_doc;
if (PyDict_SetItemString(d, "SocketType",
(PyObject *)&PySocketSock_Type) != 0)
return;
--- 3165,3172 ----
SSL_ERROR_SSL);
#endif /* USE_SSL */
if (PyDict_SetItemString(d, "SocketType",
+ (PyObject *)&PySocketSock_Type) != 0)
+ return;
+ if (PyDict_SetItemString(d, "socket",
(PyObject *)&PySocketSock_Type) != 0)
return;