diff -r 1f4b0b886a25 Modules/socketmodule.c --- a/Modules/socketmodule.c Tue Jan 14 18:14:05 2014 -0800 +++ b/Modules/socketmodule.c Tue Jan 14 19:33:35 2014 -0800 @@ -73,14 +73,6 @@ v1 is the node v2 is the ref v3 is ignored - - -Local naming conventions: - -- names starting with sock_ are socket object methods -- names starting with socket_ are module-level functions -- names starting with PySocket are exported through socketmodule.h - */ #ifdef __APPLE__ @@ -95,6 +87,33 @@ #include "Python.h" #include "structmember.h" +/*[clinic input] +module _socket +class _socket.socket + +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +/* Custom Argument Clinic converters. */ +/*[python input] +class socket_obj_converter(self_converter): + type = "PySocketSockObject *" + +class socklen_t_converter(int_converter): + type = "socklen_t" + +class DWORD_converter(CConverter): + type = "DWORD" + format_unit = "I" + +class idna_str_converter(str_converter): + type = "char *" + def converter_init(self): + super().converter_init(encoding="idna", types="bytes bytearray str") + +[python start generated code]*/ +/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /* Socket object documentation */ PyDoc_STRVAR(sock_doc, "socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) -> socket object\n\ @@ -106,39 +125,7 @@ specifying the default protocol. Keyword arguments are accepted.\n\ The socket is created as non-inheritable.\n\ \n\ -A socket object represents one endpoint of a network connection.\n\ -\n\ -Methods of socket objects (keyword arguments not allowed):\n\ -\n\ -_accept() -- accept connection, returning new socket fd and client address\n\ -bind(addr) -- bind the socket to a local address\n\ -close() -- close the socket\n\ -connect(addr) -- connect the socket to a remote address\n\ -connect_ex(addr) -- connect, return an error code instead of an exception\n\ -dup() -- return a new socket fd duplicated from fileno()\n\ -fileno() -- return underlying file descriptor\n\ -getpeername() -- return remote address [*]\n\ -getsockname() -- return local address\n\ -getsockopt(level, optname[, buflen]) -- get socket options\n\ -gettimeout() -- return timeout or None\n\ -listen(n) -- start listening for incoming connections\n\ -recv(buflen[, flags]) -- receive data\n\ -recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\ -recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\ -recvfrom_into(buffer[, nbytes, [, flags])\n\ - -- receive data and sender\'s address (into a buffer)\n\ -sendall(data[, flags]) -- send all data\n\ -send(data[, flags]) -- send data, may not send all of it\n\ -sendto(data[, flags], addr) -- send data to a given address\n\ -setblocking(0 | 1) -- set or clear the blocking I/O flag\n\ -setsockopt(level, optname, value) -- set socket options\n\ -settimeout(None | float) -- set or clear the timeout\n\ -shutdown(how) -- shut down traffic in one or both directions\n\ -if_nameindex() -- return all network interface indices and names\n\ -if_nametoindex(name) -- return the corresponding interface index\n\ -if_indextoname(index) -- return the corresponding interface name\n\ -\n\ - [*] not available on all platforms!"); +A socket object represents one endpoint of a network connection.\n"); /* XXX This is a terrible mess of platform-dependent preprocessor hacks. I hope some day someone can clean this up please... */ @@ -1955,10 +1942,47 @@ #endif /* CMSG_LEN */ -/* s._accept() -> (fd, address) */ - -static PyObject * -sock_accept(PySocketSockObject *s) +/*[clinic input] +_socket.socket._accept + + self: socket_obj + +Accept a connection. + +The socket must be bound to an address and listening for connections. The +return value is a pair (conn, address) where conn is a new socket object usable +to send and receive data on the connection, and address is the address bound to +the socket on the other end of the connection. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket__accept__doc__, +"_accept()\n" +"Accept a connection.\n" +"\n" +"The socket must be bound to an address and listening for connections. The\n" +"return value is a pair (conn, address) where conn is a new socket object usable\n" +"to send and receive data on the connection, and address is the address bound to\n" +"the socket on the other end of the connection."); + +#define _SOCKET_SOCKET__ACCEPT_METHODDEF \ + {"_accept", (PyCFunction)_socket_socket__accept, METH_NOARGS, _socket_socket__accept__doc__}, + +static PyObject * +_socket_socket__accept_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket__accept(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket__accept_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket__accept_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=6c873b0c29fe71dbb3263ac560bb139d20af8a12]*/ { sock_addr_t addrbuf; SOCKET_T newfd = INVALID_SOCKET; @@ -1972,21 +1996,21 @@ static int accept4_works = -1; #endif - if (!getsockaddrlen(s, &addrlen)) + if (!getsockaddrlen(self, &addrlen)) return NULL; memset(&addrbuf, 0, addrlen); - if (!IS_SELECTABLE(s)) + if (!IS_SELECTABLE(self)) return select_error(); - BEGIN_SELECT_LOOP(s) + BEGIN_SELECT_LOOP(self) Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); + timeout = internal_select_ex(self, 0, interval); if (!timeout) { #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if (accept4_works != 0) { - newfd = accept4(s->sock_fd, SAS2SA(&addrbuf), &addrlen, + newfd = accept4(self->sock_fd, SAS2SA(&addrbuf), &addrlen, SOCK_CLOEXEC); if (newfd == INVALID_SOCKET && accept4_works == -1) { /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ @@ -1994,9 +2018,9 @@ } } if (accept4_works == 0) - newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + newfd = accept(self->sock_fd, SAS2SA(&addrbuf), &addrlen); #else - newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + newfd = accept(self->sock_fd, SAS2SA(&addrbuf), &addrlen); #endif } Py_END_ALLOW_THREADS @@ -2005,10 +2029,10 @@ PyErr_SetString(socket_timeout, "timed out"); return NULL; } - END_SELECT_LOOP(s) + END_SELECT_LOOP(self) if (newfd == INVALID_SOCKET) - return s->errorhandler(); + return self->errorhandler(); #ifdef MS_WINDOWS if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { @@ -2035,8 +2059,8 @@ goto finally; } - addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), - addrlen, s->sock_proto); + addr = makesockaddr(self->sock_fd, SAS2SA(&addrbuf), + addrlen, self->sock_proto); if (addr == NULL) goto finally; @@ -2048,56 +2072,92 @@ return res; } -PyDoc_STRVAR(accept_doc, -"_accept() -> (integer, address info)\n\ -\n\ -Wait for an incoming connection. Return a new socket file descriptor\n\ -representing the connection, and the address of the client.\n\ -For IP sockets, the address info is a pair (hostaddr, port)."); - -/* s.setblocking(flag) method. Argument: - False -- non-blocking mode; same as settimeout(0) - True -- blocking mode; same as settimeout(None) -*/ - -static PyObject * -sock_setblocking(PySocketSockObject *s, PyObject *arg) + +/* Maybe convert this to take a bool? */ +/*[clinic input] +_socket.socket.setblocking + + self: socket_obj + flag: object + / + +Set blocking or non-blocking mode of the socket. + +If flag is false, the socket is set to non-blocking, else to blocking mode. +This is equivalent to settimeout(None) or settimeout(0.0) respectively. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_setblocking__doc__, +"setblocking(flag)\n" +"Set blocking or non-blocking mode of the socket.\n" +"\n" +"If flag is false, the socket is set to non-blocking, else to blocking mode.\n" +"This is equivalent to settimeout(None) or settimeout(0.0) respectively."); + +#define _SOCKET_SOCKET_SETBLOCKING_METHODDEF \ + {"setblocking", (PyCFunction)_socket_socket_setblocking, METH_O, _socket_socket_setblocking__doc__}, + +static PyObject * +_socket_socket_setblocking(PySocketSockObject *self, PyObject *flag) +/*[clinic end generated code: checksum=68ee117fed799a0685be6edfc5e2179504a9a010]*/ { long block; - block = PyLong_AsLong(arg); + block = PyLong_AsLong(flag); if (block == -1 && PyErr_Occurred()) return NULL; - s->sock_timeout = block ? -1.0 : 0.0; - internal_setblocking(s, block); + self->sock_timeout = block ? -1.0 : 0.0; + internal_setblocking(self, block); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(setblocking_doc, -"setblocking(flag)\n\ -\n\ -Set the socket to blocking (flag is true) or non-blocking (false).\n\ -setblocking(True) is equivalent to settimeout(None);\n\ -setblocking(False) is equivalent to settimeout(0.0)."); - -/* s.settimeout(timeout) method. Argument: - None -- no timeout, blocking mode; same as setblocking(True) - 0.0 -- non-blocking mode; same as setblocking(False) - > 0 -- timeout mode; operations time out after timeout seconds - < 0 -- illegal; raises an exception -*/ -static PyObject * -sock_settimeout(PySocketSockObject *s, PyObject *arg) + +/*[clinic input] +_socket.socket.settimeout + + self: socket_obj + value: object + Nonnegative float in seconds or None + / + +Set a timeout on socket operations. + +The value argument can be a nonnegative floating point number expressing +seconds, or None. If a non-zero value is given, subsequent socket operations +will raise a timeout exception if the timeout period value has elapsed before +the operation has completed. If zero is given, the socket is put in +non-blocking mode. If None is given, the socket is put in blocking mode. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_settimeout__doc__, +"settimeout(value)\n" +"Set a timeout on socket operations.\n" +"\n" +" value\n" +" Nonnegative float in seconds or None\n" +"\n" +"The value argument can be a nonnegative floating point number expressing\n" +"seconds, or None. If a non-zero value is given, subsequent socket operations\n" +"will raise a timeout exception if the timeout period value has elapsed before\n" +"the operation has completed. If zero is given, the socket is put in\n" +"non-blocking mode. If None is given, the socket is put in blocking mode."); + +#define _SOCKET_SOCKET_SETTIMEOUT_METHODDEF \ + {"settimeout", (PyCFunction)_socket_socket_settimeout, METH_O, _socket_socket_settimeout__doc__}, + +static PyObject * +_socket_socket_settimeout(PySocketSockObject *self, PyObject *value) +/*[clinic end generated code: checksum=16bf12da2cfaa90e08918317c0e13575fd99e86e]*/ { double timeout; - if (arg == Py_None) + if (value == Py_None) timeout = -1.0; else { - timeout = PyFloat_AsDouble(arg); + timeout = PyFloat_AsDouble(value); if (timeout < 0.0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, @@ -2106,106 +2166,217 @@ } } - s->sock_timeout = timeout; - internal_setblocking(s, timeout < 0.0); + self->sock_timeout = timeout; + internal_setblocking(self, timeout < 0.0); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(settimeout_doc, -"settimeout(timeout)\n\ -\n\ -Set a timeout on socket operations. 'timeout' can be a float,\n\ -giving in seconds, or None. Setting a timeout of None disables\n\ -the timeout feature and is equivalent to setblocking(1).\n\ -Setting a timeout of zero is the same as setblocking(0)."); - -/* s.gettimeout() method. - Returns the timeout associated with a socket. */ -static PyObject * -sock_gettimeout(PySocketSockObject *s) -{ - if (s->sock_timeout < 0.0) { + +/*[clinic input] +_socket.socket.gettimeout + + self: socket_obj + +Return the timeout associated with socket operations. + +Return value is the timeout in seconds(float) or None if no timeout is set. +This reflects the last call to setblocking() or settimeout(). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_gettimeout__doc__, +"gettimeout()\n" +"Return the timeout associated with socket operations.\n" +"\n" +"Return value is the timeout in seconds(float) or None if no timeout is set.\n" +"This reflects the last call to setblocking() or settimeout()."); + +#define _SOCKET_SOCKET_GETTIMEOUT_METHODDEF \ + {"gettimeout", (PyCFunction)_socket_socket_gettimeout, METH_NOARGS, _socket_socket_gettimeout__doc__}, + +static PyObject * +_socket_socket_gettimeout_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket_gettimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_gettimeout_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket_gettimeout_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=f032b6d3e7bedea9abff1c5db2d63f259fac84c0]*/ +{ + if (self->sock_timeout < 0.0) { Py_INCREF(Py_None); return Py_None; } else - return PyFloat_FromDouble(s->sock_timeout); -} - -PyDoc_STRVAR(gettimeout_doc, -"gettimeout() -> timeout\n\ -\n\ -Returns the timeout in seconds (float) associated with socket \n\ -operations. A timeout of None indicates that timeouts on socket \n\ -operations are disabled."); - -/* s.setsockopt() method. - With an integer third argument, sets an integer option. - With a string third argument, sets an option from a buffer; - use optional built-in module 'struct' to encode the string. */ - -static PyObject * -sock_setsockopt(PySocketSockObject *s, PyObject *args) -{ + return PyFloat_FromDouble(self->sock_timeout); +} + + +/*[clinic input] +_socket.socket.setsockopt + + self: socket_obj + level: int + optname: int + value: object + An integer, or a bytes object representing a buffer. + / + +Set the value of the given socket option. + +see the Unix manual page setsockopt(2) for level and optname. The needed +symbolic constants are defined in this module (SO_* etc.). The value can be an +integer or a bytes object representing a buffer. In the latter case it is up to +the caller to ensure that the bytestring contains the proper bits (see the +optional built-in module struct for a way to encode C structures as +bytestrings). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_setsockopt__doc__, +"setsockopt(level, optname, value)\n" +"Set the value of the given socket option.\n" +"\n" +" value\n" +" An integer, or a bytes object representing a buffer.\n" +"\n" +"see the Unix manual page setsockopt(2) for level and optname. The needed\n" +"symbolic constants are defined in this module (SO_* etc.). The value can be an\n" +"integer or a bytes object representing a buffer. In the latter case it is up to\n" +"the caller to ensure that the bytestring contains the proper bits (see the\n" +"optional built-in module struct for a way to encode C structures as\n" +"bytestrings)."); + +#define _SOCKET_SOCKET_SETSOCKOPT_METHODDEF \ + {"setsockopt", (PyCFunction)_socket_socket_setsockopt, METH_VARARGS, _socket_socket_setsockopt__doc__}, + +static PyObject * +_socket_socket_setsockopt_impl(PySocketSockObject *self, int level, int optname, PyObject *value); + +static PyObject * +_socket_socket_setsockopt(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; int level; int optname; + PyObject *value; + + if (!PyArg_ParseTuple(args, + "iiO:setsockopt", + &level, &optname, &value)) + goto exit; + return_value = _socket_socket_setsockopt_impl((PySocketSockObject *)self, level, optname, value); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_setsockopt_impl(PySocketSockObject *self, int level, int optname, PyObject *value) +/*[clinic end generated code: checksum=c77999d50b790b0d49ccbb817e2625d2dd03f567]*/ +{ int res; char *buf; - int buflen; + Py_buffer buffer; + Py_ssize_t buflen; int flag; - if (PyArg_ParseTuple(args, "iii:setsockopt", - &level, &optname, &flag)) { + if (PyLong_Check(value)) { + flag = PyLong_AsLong(value); buf = (char *) &flag; - buflen = sizeof flag; - } - else { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "iiy#:setsockopt", - &level, &optname, &buf, &buflen)) + buflen = sizeof(flag); + } else { + if (PyObject_GetBuffer(value, &buffer, PyBUF_SIMPLE)) return NULL; - } - res = setsockopt(s->sock_fd, level, optname, (void *)buf, buflen); + buf = buffer.buf; + buflen = buffer.len; + } + + res = setsockopt(self->sock_fd, level, optname, (void *)buf, buflen); + if (res < 0) - return s->errorhandler(); + return self->errorhandler(); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(setsockopt_doc, -"setsockopt(level, option, value)\n\ -\n\ -Set a socket option. See the Unix manual for level and option.\n\ -The value argument can either be an integer or a string."); - - -/* s.getsockopt() method. - With two arguments, retrieves an integer option. - With a third integer argument, retrieves a string buffer of that size; - use optional built-in module 'struct' to decode the string. */ - -static PyObject * -sock_getsockopt(PySocketSockObject *s, PyObject *args) -{ + +/*[clinic input] +_socket.socket.getsockopt + + self: socket_obj + level: int + Level of the socket API to get an option from. + optname: int + Specific option to retrieve. + buflen: socklen_t = 0 + Nonnegative length of the returned bytes buffer. + / + +Return the value of the given socket option. + +See the Unix man page getsockopt(2) for level and optname. The needed symbolic constants (SO_* etc.) are defined in this module. If buflen is absent, an integer option is assumed and its integer value is returned by the function. If buflen is present, it specifies the maximum length of the buffer used to receive the option in, and this buffer is returned as a bytes object. It is up to the caller to decode the contents of the buffer (see the optional built-in module struct for a way to decode C structures encoded as byte strings). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_getsockopt__doc__, +"getsockopt(level, optname, buflen=0)\n" +"Return the value of the given socket option.\n" +"\n" +" level\n" +" Level of the socket API to get an option from.\n" +" optname\n" +" Specific option to retrieve.\n" +" buflen\n" +" Nonnegative length of the returned bytes buffer.\n" +"\n" +"See the Unix man page getsockopt(2) for level and optname. The needed symbolic constants (SO_* etc.) are defined in this module. If buflen is absent, an integer option is assumed and its integer value is returned by the function. If buflen is present, it specifies the maximum length of the buffer used to receive the option in, and this buffer is returned as a bytes object. It is up to the caller to decode the contents of the buffer (see the optional built-in module struct for a way to decode C structures encoded as byte strings)."); + +#define _SOCKET_SOCKET_GETSOCKOPT_METHODDEF \ + {"getsockopt", (PyCFunction)_socket_socket_getsockopt, METH_VARARGS, _socket_socket_getsockopt__doc__}, + +static PyObject * +_socket_socket_getsockopt_impl(PySocketSockObject *self, int level, int optname, socklen_t buflen); + +static PyObject * +_socket_socket_getsockopt(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; int level; int optname; + socklen_t buflen = 0; + + if (!PyArg_ParseTuple(args, + "ii|i:getsockopt", + &level, &optname, &buflen)) + goto exit; + return_value = _socket_socket_getsockopt_impl((PySocketSockObject *)self, level, optname, buflen); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_getsockopt_impl(PySocketSockObject *self, int level, int optname, socklen_t buflen) +/*[clinic end generated code: checksum=de168d9fec0ee5adfea923c13d1c955460974272]*/ +{ int res; PyObject *buf; - socklen_t buflen = 0; - - if (!PyArg_ParseTuple(args, "ii|i:getsockopt", - &level, &optname, &buflen)) - return NULL; if (buflen == 0) { int flag = 0; socklen_t flagsize = sizeof flag; - res = getsockopt(s->sock_fd, level, optname, + res = getsockopt(self->sock_fd, level, optname, (void *)&flag, &flagsize); if (res < 0) - return s->errorhandler(); + return self->errorhandler(); return PyLong_FromLong(flag); } if (buflen <= 0 || buflen > 1024) { @@ -2216,63 +2387,96 @@ buf = PyBytes_FromStringAndSize((char *)NULL, buflen); if (buf == NULL) return NULL; - res = getsockopt(s->sock_fd, level, optname, + res = getsockopt(self->sock_fd, level, optname, (void *)PyBytes_AS_STRING(buf), &buflen); if (res < 0) { Py_DECREF(buf); - return s->errorhandler(); + return self->errorhandler(); } _PyBytes_Resize(&buf, buflen); return buf; } -PyDoc_STRVAR(getsockopt_doc, -"getsockopt(level, option[, buffersize]) -> value\n\ -\n\ -Get a socket option. See the Unix manual for level and option.\n\ -If a nonzero buffersize argument is given, the return value is a\n\ -string of that length; otherwise it is an integer."); - - -/* s.bind(sockaddr) method */ - -static PyObject * -sock_bind(PySocketSockObject *s, PyObject *addro) + +/*[clinic input] +_socket.socket.bind + + self: socket_obj + address: object + / + +Bind the socket to the given address. + +The socket must not already be bound. The format of address depends on the +address family. For IP sockets, address is a pair (hostaddr, port). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_bind__doc__, +"bind(address)\n" +"Bind the socket to the given address.\n" +"\n" +"The socket must not already be bound. The format of address depends on the\n" +"address family. For IP sockets, address is a pair (hostaddr, port)."); + +#define _SOCKET_SOCKET_BIND_METHODDEF \ + {"bind", (PyCFunction)_socket_socket_bind, METH_O, _socket_socket_bind__doc__}, + +static PyObject * +_socket_socket_bind(PySocketSockObject *self, PyObject *address) +/*[clinic end generated code: checksum=c9f41f72e545097425265df826409e55640a7871]*/ { sock_addr_t addrbuf; int addrlen; int res; - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) + if (!getsockaddrarg(self, address, SAS2SA(&addrbuf), &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS - res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen); + res = bind(self->sock_fd, SAS2SA(&addrbuf), addrlen); Py_END_ALLOW_THREADS if (res < 0) - return s->errorhandler(); + return self->errorhandler(); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(bind_doc, -"bind(address)\n\ -\n\ -Bind the socket to a local address. For IP sockets, the address is a\n\ -pair (host, port); the host must refer to the local host. For raw packet\n\ -sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])"); - - -/* s.close() method. - Set the file descriptor to -1 so operations tried subsequently - will surely fail. */ - -static PyObject * -sock_close(PySocketSockObject *s) + +/*[clinic input] +_socket.socket.close + + self: socket_obj + +Close the socket. It cannot be used after this call. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_close__doc__, +"close()\n" +"Close the socket. It cannot be used after this call."); + +#define _SOCKET_SOCKET_CLOSE_METHODDEF \ + {"close", (PyCFunction)_socket_socket_close, METH_NOARGS, _socket_socket_close__doc__}, + +static PyObject * +_socket_socket_close_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket_close(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_close_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket_close_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=1f853dca812ec9adad6dc333f97d905cfa614da8]*/ { SOCKET_T fd; - if ((fd = s->sock_fd) != -1) { - s->sock_fd = -1; + if ((fd = self->sock_fd) != -1) { + self->sock_fd = -1; Py_BEGIN_ALLOW_THREADS (void) SOCKETCLOSE(fd); Py_END_ALLOW_THREADS @@ -2281,25 +2485,52 @@ return Py_None; } -PyDoc_STRVAR(close_doc, -"close()\n\ -\n\ -Close the socket. It cannot be used after this call."); - -static PyObject * -sock_detach(PySocketSockObject *s) -{ - SOCKET_T fd = s->sock_fd; - s->sock_fd = -1; + +/*[clinic input] +_socket.socket.detach + + self: socket_obj + +Close the socket object without closing the underlying file descriptor. + +The object cannot be used after this call, but the file descriptor can be +reused for other purposes. The file descriptor is returned, and can be +reused for other purposes. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_detach__doc__, +"detach()\n" +"Close the socket object without closing the underlying file descriptor.\n" +"\n" +"The object cannot be used after this call, but the file descriptor can be\n" +"reused for other purposes. The file descriptor is returned, and can be\n" +"reused for other purposes."); + +#define _SOCKET_SOCKET_DETACH_METHODDEF \ + {"detach", (PyCFunction)_socket_socket_detach, METH_NOARGS, _socket_socket_detach__doc__}, + +static PyObject * +_socket_socket_detach_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_detach_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket_detach_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=8db2a606d7d19bdb12da1e0d6eee76a16493c5b0]*/ +{ + SOCKET_T fd = self->sock_fd; + self->sock_fd = -1; return PyLong_FromSocket_t(fd); } -PyDoc_STRVAR(detach_doc, -"detach()\n\ -\n\ -Close the socket object without closing the underlying file descriptor.\n\ -The object cannot be used after this call, but the file descriptor\n\ -can be reused for other purposes. The file descriptor is returned."); static int internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, @@ -2390,21 +2621,43 @@ return res; } -/* s.connect(sockaddr) method */ - -static PyObject * -sock_connect(PySocketSockObject *s, PyObject *addro) +/*[clinic input] +_socket.socket.connect + + self: socket_obj + address: object + / + +Connect to a remote socket at address. + +The format of address depends on the address family. For IP sockets, address is +a pair (hostaddr, port). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_connect__doc__, +"connect(address)\n" +"Connect to a remote socket at address.\n" +"\n" +"The format of address depends on the address family. For IP sockets, address is\n" +"a pair (hostaddr, port)."); + +#define _SOCKET_SOCKET_CONNECT_METHODDEF \ + {"connect", (PyCFunction)_socket_socket_connect, METH_O, _socket_socket_connect__doc__}, + +static PyObject * +_socket_socket_connect(PySocketSockObject *self, PyObject *address) +/*[clinic end generated code: checksum=12ae759b8e1c582cfe37923b587c96cd0b4c1409]*/ { sock_addr_t addrbuf; int addrlen; int res; int timeout; - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) + if (!getsockaddrarg(self, address, SAS2SA(&addrbuf), &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS - res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); + res = internal_connect(self, SAS2SA(&addrbuf), addrlen, &timeout); Py_END_ALLOW_THREADS if (timeout == 1) { @@ -2412,33 +2665,53 @@ return NULL; } if (res != 0) - return s->errorhandler(); + return self->errorhandler(); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(connect_doc, -"connect(address)\n\ -\n\ -Connect the socket to a remote address. For IP sockets, the address\n\ -is a pair (host, port)."); - - -/* s.connect_ex(sockaddr) method */ - -static PyObject * -sock_connect_ex(PySocketSockObject *s, PyObject *addro) + +/*[clinic input] +_socket.socket.connect_ex + + self: socket_obj + address: object + / + +Like connect(), but return some errors instead of raising an exception. + +Returns an error indicator instead of raising an exception for errors returned +by the C-level connect() call. Other problems, such as “host not found,” can +still raise exceptions. The error indicator is 0 if the operation succeeded, +otherwise the value of the errno variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_connect_ex__doc__, +"connect_ex(address)\n" +"Like connect(), but return some errors instead of raising an exception.\n" +"\n" +"Returns an error indicator instead of raising an exception for errors returned\n" +"by the C-level connect() call. Other problems, such as “host not found,” can\n" +"still raise exceptions. The error indicator is 0 if the operation succeeded,\n" +"otherwise the value of the errno variable."); + +#define _SOCKET_SOCKET_CONNECT_EX_METHODDEF \ + {"connect_ex", (PyCFunction)_socket_socket_connect_ex, METH_O, _socket_socket_connect_ex__doc__}, + +static PyObject * +_socket_socket_connect_ex(PySocketSockObject *self, PyObject *address) +/*[clinic end generated code: checksum=463caf814772bfc881970059f5352ffbce351841]*/ { sock_addr_t addrbuf; int addrlen; int res; int timeout; - if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) + if (!getsockaddrarg(self, address, SAS2SA(&addrbuf), &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS - res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); + res = internal_connect(self, SAS2SA(&addrbuf), addrlen, &timeout); Py_END_ALLOW_THREADS /* Signals are not errors (though they may raise exceptions). Adapted @@ -2451,118 +2724,224 @@ return PyLong_FromLong((long) res); } -PyDoc_STRVAR(connect_ex_doc, -"connect_ex(address) -> errno\n\ -\n\ -This is like connect(address), but returns an error code (the errno value)\n\ -instead of raising an exception when an error occurs."); - - -/* s.fileno() method */ - -static PyObject * -sock_fileno(PySocketSockObject *s) -{ - return PyLong_FromSocket_t(s->sock_fd); -} - -PyDoc_STRVAR(fileno_doc, -"fileno() -> integer\n\ -\n\ -Return the integer file descriptor of the socket."); - - -/* s.getsockname() method */ - -static PyObject * -sock_getsockname(PySocketSockObject *s) + +/*[clinic input] +_socket.socket.fileno + + self: socket_obj + +Return the integer file descriptor of the socket. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_fileno__doc__, +"fileno()\n" +"Return the integer file descriptor of the socket."); + +#define _SOCKET_SOCKET_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_socket_socket_fileno, METH_NOARGS, _socket_socket_fileno__doc__}, + +static PyObject * +_socket_socket_fileno_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_fileno_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket_fileno_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=b418fde7b78242ea829363e312ef3442f4f58ee1]*/ +{ + return PyLong_FromSocket_t(self->sock_fd); +} + + + +/*[clinic input] +_socket.socket.getsockname + + self: socket_obj + +Return the socket's own address. + +The format of the address returned depends on the address family. For IP +sockets, address is a pair (hostaddr, port). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_getsockname__doc__, +"getsockname()\n" +"Return the socket\'s own address.\n" +"\n" +"The format of the address returned depends on the address family. For IP\n" +"sockets, address is a pair (hostaddr, port)."); + +#define _SOCKET_SOCKET_GETSOCKNAME_METHODDEF \ + {"getsockname", (PyCFunction)_socket_socket_getsockname, METH_NOARGS, _socket_socket_getsockname__doc__}, + +static PyObject * +_socket_socket_getsockname_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket_getsockname(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_getsockname_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket_getsockname_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=a1fee0ea1af8cc84529c106b8ab10c287e0aa7e8]*/ { sock_addr_t addrbuf; int res; socklen_t addrlen; - if (!getsockaddrlen(s, &addrlen)) + if (!getsockaddrlen(self, &addrlen)) return NULL; memset(&addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS - res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + res = getsockname(self->sock_fd, SAS2SA(&addrbuf), &addrlen); Py_END_ALLOW_THREADS if (res < 0) - return s->errorhandler(); - return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, - s->sock_proto); -} - -PyDoc_STRVAR(getsockname_doc, -"getsockname() -> address info\n\ -\n\ -Return the address of the local endpoint. For IP sockets, the address\n\ -info is a pair (hostaddr, port)."); + return self->errorhandler(); + return makesockaddr(self->sock_fd, SAS2SA(&addrbuf), addrlen, + self->sock_proto); +} #ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */ -/* s.getpeername() method */ - -static PyObject * -sock_getpeername(PySocketSockObject *s) +/*[clinic input] +_socket.socket.getpeername + + self: socket_obj + +Return the remote address to which the socket is connected. + +The format of the address returned depends on the address family. For IP +sockets, address is a pair (hostaddr, port). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_getpeername__doc__, +"getpeername()\n" +"Return the remote address to which the socket is connected.\n" +"\n" +"The format of the address returned depends on the address family. For IP\n" +"sockets, address is a pair (hostaddr, port)."); + +#define _SOCKET_SOCKET_GETPEERNAME_METHODDEF \ + {"getpeername", (PyCFunction)_socket_socket_getpeername, METH_NOARGS, _socket_socket_getpeername__doc__}, + +static PyObject * +_socket_socket_getpeername_impl(PySocketSockObject *self); + +static PyObject * +_socket_socket_getpeername(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_getpeername_impl((PySocketSockObject *)self); + + return return_value; +} + +static PyObject * +_socket_socket_getpeername_impl(PySocketSockObject *self) +/*[clinic end generated code: checksum=089e82daf3c64d5276611984bc9a925857e7069e]*/ { sock_addr_t addrbuf; int res; socklen_t addrlen; - if (!getsockaddrlen(s, &addrlen)) + if (!getsockaddrlen(self, &addrlen)) return NULL; memset(&addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS - res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + res = getpeername(self->sock_fd, SAS2SA(&addrbuf), &addrlen); Py_END_ALLOW_THREADS if (res < 0) - return s->errorhandler(); - return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, - s->sock_proto); -} - -PyDoc_STRVAR(getpeername_doc, -"getpeername() -> address info\n\ -\n\ -Return the address of the remote endpoint. For IP sockets, the address\n\ -info is a pair (hostaddr, port)."); + return self->errorhandler(); + return makesockaddr(self->sock_fd, SAS2SA(&addrbuf), addrlen, + self->sock_proto); +} #endif /* HAVE_GETPEERNAME */ -/* s.listen(n) method */ - -static PyObject * -sock_listen(PySocketSockObject *s, PyObject *arg) -{ +/*[clinic input] +_socket.socket.listen + + self: socket_obj + backlog: int + Maximum number of queued connections. + +Listen for connections made to the socket. + +The backlog argument specifies the maximum number of queued connections and +should be at least 0; the maximum value is system-dependent (usually 5), the +minimum value is forced to 0. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_listen__doc__, +"listen(backlog)\n" +"Listen for connections made to the socket.\n" +"\n" +" backlog\n" +" Maximum number of queued connections.\n" +"\n" +"The backlog argument specifies the maximum number of queued connections and\n" +"should be at least 0; the maximum value is system-dependent (usually 5), the\n" +"minimum value is forced to 0."); + +#define _SOCKET_SOCKET_LISTEN_METHODDEF \ + {"listen", (PyCFunction)_socket_socket_listen, METH_VARARGS|METH_KEYWORDS, _socket_socket_listen__doc__}, + +static PyObject * +_socket_socket_listen_impl(PySocketSockObject *self, int backlog); + +static PyObject * +_socket_socket_listen(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"backlog", NULL}; int backlog; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:listen", _keywords, + &backlog)) + goto exit; + return_value = _socket_socket_listen_impl((PySocketSockObject *)self, backlog); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_listen_impl(PySocketSockObject *self, int backlog) +/*[clinic end generated code: checksum=dca3732765a0339a59cf5c44b4bb13af8ff2e4a5]*/ +{ int res; - backlog = _PyLong_AsInt(arg); - if (backlog == -1 && PyErr_Occurred()) - return NULL; Py_BEGIN_ALLOW_THREADS /* To avoid problems on systems that don't allow a negative backlog * (which doesn't make sense anyway) we force a minimum value of 0. */ if (backlog < 0) backlog = 0; - res = listen(s->sock_fd, backlog); + res = listen(self->sock_fd, backlog); Py_END_ALLOW_THREADS if (res < 0) - return s->errorhandler(); + return self->errorhandler(); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(listen_doc, -"listen(backlog)\n\ -\n\ -Enable a server to accept connections. The backlog argument must be at\n\ -least 0 (if it is lower, it is set to 0); it specifies the number of\n\ -unaccepted connections that the system will allow before refusing new\n\ -connections."); - /* * This is the guts of the recv() and recv_into() methods, which reads into a @@ -2617,38 +2996,84 @@ } -/* s.recv(nbytes [,flags]) method */ - -static PyObject * -sock_recv(PySocketSockObject *s, PyObject *args) -{ - Py_ssize_t recvlen, outlen; +/*[clinic input] +_socket.socket.recv + + self: socket_obj + bufsize: Py_ssize_t + Maximum number of bytes to receive. Cannot be negative. + flags: int = 0 + See the Unix manual page recv(2) for info. + / + +Receive data from the socket. + +The return value is a bytes object representing the data received. The maximum +amount of data to be received at once is specified by bufsize. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_recv__doc__, +"recv(bufsize, flags=0)\n" +"Receive data from the socket.\n" +"\n" +" bufsize\n" +" Maximum number of bytes to receive. Cannot be negative.\n" +" flags\n" +" See the Unix manual page recv(2) for info.\n" +"\n" +"The return value is a bytes object representing the data received. The maximum\n" +"amount of data to be received at once is specified by bufsize."); + +#define _SOCKET_SOCKET_RECV_METHODDEF \ + {"recv", (PyCFunction)_socket_socket_recv, METH_VARARGS, _socket_socket_recv__doc__}, + +static PyObject * +_socket_socket_recv_impl(PySocketSockObject *self, Py_ssize_t bufsize, int flags); + +static PyObject * +_socket_socket_recv(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t bufsize; int flags = 0; + + if (!PyArg_ParseTuple(args, + "n|i:recv", + &bufsize, &flags)) + goto exit; + return_value = _socket_socket_recv_impl((PySocketSockObject *)self, bufsize, flags); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_recv_impl(PySocketSockObject *self, Py_ssize_t bufsize, int flags) +/*[clinic end generated code: checksum=f2df103803cd916ff08c0f4a64de1b6943e70130]*/ +{ + Py_ssize_t outlen; PyObject *buf; - if (!PyArg_ParseTuple(args, "n|i:recv", &recvlen, &flags)) + if (bufsize < 0) { + PyErr_SetString(PyExc_ValueError, + "negative buflen"); return NULL; - - if (recvlen < 0) { - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recv"); - return NULL; } /* Allocate a new string. */ - buf = PyBytes_FromStringAndSize((char *) 0, recvlen); + buf = PyBytes_FromStringAndSize(NULL, bufsize); if (buf == NULL) return NULL; /* Call the guts */ - outlen = sock_recv_guts(s, PyBytes_AS_STRING(buf), recvlen, flags); + outlen = sock_recv_guts(self, PyBytes_AS_STRING(buf), bufsize, flags); if (outlen < 0) { /* An error occurred, release the string and return an error. */ Py_DECREF(buf); return NULL; } - if (outlen != recvlen) { + if (outlen != bufsize) { /* We did not read as many bytes as we anticipated, resize the string if possible and be successful. */ _PyBytes_Resize(&buf, outlen); @@ -2657,76 +3082,104 @@ return buf; } -PyDoc_STRVAR(recv_doc, -"recv(buffersize[, flags]) -> data\n\ -\n\ -Receive up to buffersize bytes from the socket. For the optional flags\n\ -argument, see the Unix manual. When no data is available, block until\n\ -at least one byte is available or until the remote end is closed. When\n\ -the remote end is closed and all data is read, return the empty string."); - - -/* s.recv_into(buffer, [nbytes [,flags]]) method */ - -static PyObject* -sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; - + +/*[clinic input] +_socket.socket.recv_into + + self: socket_obj + buffer: Py_buffer(types='bytearray rwbuffer') + bytearray object to store data into. + nbytes: Py_ssize_t = 0 + Maximum number of bytes to receive. Cannot be negative. + flags: int = 0 + See the Unix manual page recv(2) for info. + +Receive data from the socket into the specified buffer. + +If nbytes is not specified (or 0), receive up to the size available in the +given buffer. Returns the number of bytes received. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_recv_into__doc__, +"recv_into(buffer, nbytes=0, flags=0)\n" +"Receive data from the socket into the specified buffer.\n" +"\n" +" buffer\n" +" bytearray object to store data into.\n" +" nbytes\n" +" Maximum number of bytes to receive. Cannot be negative.\n" +" flags\n" +" See the Unix manual page recv(2) for info.\n" +"\n" +"If nbytes is not specified (or 0), receive up to the size available in the\n" +"given buffer. Returns the number of bytes received."); + +#define _SOCKET_SOCKET_RECV_INTO_METHODDEF \ + {"recv_into", (PyCFunction)_socket_socket_recv_into, METH_VARARGS|METH_KEYWORDS, _socket_socket_recv_into__doc__}, + +static PyObject * +_socket_socket_recv_into_impl(PySocketSockObject *self, Py_buffer *buffer, Py_ssize_t nbytes, int flags); + +static PyObject * +_socket_socket_recv_into(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"buffer", "nbytes", "flags", NULL}; + Py_buffer buffer = {NULL, NULL}; + Py_ssize_t nbytes = 0; int flags = 0; - Py_buffer pbuf; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "w*|ni:recv_into", _keywords, + &buffer, &nbytes, &flags)) + goto exit; + return_value = _socket_socket_recv_into_impl((PySocketSockObject *)self, &buffer, nbytes, flags); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) + PyBuffer_Release(&buffer); + + return return_value; +} + +static PyObject * +_socket_socket_recv_into_impl(PySocketSockObject *self, Py_buffer *buffer, Py_ssize_t nbytes, int flags) +/*[clinic end generated code: checksum=be1908141c365c4fec1e78cf03bc079519e9b79f]*/ +{ char *buf; - Py_ssize_t buflen, readlen, recvlen = 0; - - /* Get the buffer's memory */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recv_into", kwlist, - &pbuf, &recvlen, &flags)) + Py_ssize_t buflen, readlen; + + buf = buffer->buf; + buflen = buffer->len; + + if (nbytes < 0) { + PyErr_SetString(PyExc_ValueError, + "negative nbytes"); return NULL; - buf = pbuf.buf; - buflen = pbuf.len; - - if (recvlen < 0) { - PyBuffer_Release(&pbuf); - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recv_into"); - return NULL; - } - if (recvlen == 0) { + } + if (nbytes == 0) { /* If nbytes was not specified, use the buffer's length */ - recvlen = buflen; - } - + nbytes = buflen; + } /* Check if the buffer is large enough */ - if (buflen < recvlen) { - PyBuffer_Release(&pbuf); + if (buflen < nbytes ) { PyErr_SetString(PyExc_ValueError, "buffer too small for requested bytes"); return NULL; } /* Call the guts */ - readlen = sock_recv_guts(s, buf, recvlen, flags); - if (readlen < 0) { + readlen = sock_recv_guts(self, buf, nbytes, flags); + if (readlen < 0) /* Return an error. */ - PyBuffer_Release(&pbuf); return NULL; - } - - PyBuffer_Release(&pbuf); + /* Return the number of bytes read. Note that we do not do anything special here in the case that readlen < recvlen. */ return PyLong_FromSsize_t(readlen); } -PyDoc_STRVAR(recv_into_doc, -"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\ -\n\ -A version of recv() that stores its data into a buffer rather than creating \n\ -a new string. Receive up to buffersize bytes from the socket. If buffersize \n\ -is not specified (or 0), receive up to the size available in the given buffer.\n\ -\n\ -See recv() for documentation about the flags."); - /* * This is the guts of the recvfrom() and recvfrom_into() methods, which reads @@ -2792,37 +3245,86 @@ return n; } -/* s.recvfrom(nbytes [,flags]) method */ - -static PyObject * -sock_recvfrom(PySocketSockObject *s, PyObject *args) +/*[clinic input] +_socket.socket.recvfrom + + self: socket_obj + bufsize: Py_ssize_t + Maximum number of bytes to receive. + flags: int = 0 + See the Unix manual page recv(2) for info. + / + +Receive data from the socket, along with the sender's address info. + +The return value is a pair (bytes, address) where bytes is a bytes object +representing the data received and address is the address of the socket sending +the data. The format of address depends on the address family. For IP sockets, +address is a pair (hostaddr, port). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_recvfrom__doc__, +"recvfrom(bufsize, flags=0)\n" +"Receive data from the socket, along with the sender\'s address info.\n" +"\n" +" bufsize\n" +" Maximum number of bytes to receive.\n" +" flags\n" +" See the Unix manual page recv(2) for info.\n" +"\n" +"The return value is a pair (bytes, address) where bytes is a bytes object\n" +"representing the data received and address is the address of the socket sending\n" +"the data. The format of address depends on the address family. For IP sockets,\n" +"address is a pair (hostaddr, port)."); + +#define _SOCKET_SOCKET_RECVFROM_METHODDEF \ + {"recvfrom", (PyCFunction)_socket_socket_recvfrom, METH_VARARGS, _socket_socket_recvfrom__doc__}, + +static PyObject * +_socket_socket_recvfrom_impl(PySocketSockObject *self, Py_ssize_t bufsize, int flags); + +static PyObject * +_socket_socket_recvfrom(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t bufsize; + int flags = 0; + + if (!PyArg_ParseTuple(args, + "n|i:recvfrom", + &bufsize, &flags)) + goto exit; + return_value = _socket_socket_recvfrom_impl((PySocketSockObject *)self, bufsize, flags); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_recvfrom_impl(PySocketSockObject *self, Py_ssize_t bufsize, int flags) +/*[clinic end generated code: checksum=a6b52b3ba0de6daeb6437b65678c2138d992edb2]*/ { PyObject *buf = NULL; PyObject *addr = NULL; PyObject *ret = NULL; - int flags = 0; - Py_ssize_t recvlen, outlen; - - if (!PyArg_ParseTuple(args, "n|i:recvfrom", &recvlen, &flags)) + Py_ssize_t outlen; + + if (bufsize < 0) { + PyErr_SetString(PyExc_ValueError, + "negative bufsize"); return NULL; - - if (recvlen < 0) { - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recvfrom"); - return NULL; - } - - buf = PyBytes_FromStringAndSize((char *) 0, recvlen); + } + + buf = PyBytes_FromStringAndSize(NULL, bufsize); if (buf == NULL) return NULL; - outlen = sock_recvfrom_guts(s, PyBytes_AS_STRING(buf), - recvlen, flags, &addr); - if (outlen < 0) { + outlen = sock_recvfrom_guts(self, PyBytes_AS_STRING(buf), + bufsize, flags, &addr); + if (outlen < 0) goto finally; - } - - if (outlen != recvlen) { + + if (outlen != bufsize) { /* We did not read as many bytes as we anticipated, resize the string if possible and be successful. */ if (_PyBytes_Resize(&buf, outlen) < 0) @@ -2838,68 +3340,112 @@ return ret; } -PyDoc_STRVAR(recvfrom_doc, -"recvfrom(buffersize[, flags]) -> (data, address info)\n\ -\n\ -Like recv(buffersize, flags) but also return the sender's address info."); - - -/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */ - -static PyObject * -sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) -{ - static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; - + +/*[clinic input] +_socket.socket.recvfrom_into + + self: socket_obj + buffer: Py_buffer(types='bytearray rwbuffer') + bytearray object to store data into. + nbytes: Py_ssize_t = 0 + Maximum number of bytes to receive. Cannot be negative. + flags: int = 0 + See the Unix manual page recv(2) for info. + +Receive data from the socket into the specified buffer. + +If nbytes is not specified (or 0), receive up to the size available in the +given buffer. The return value is a pair (nbytes, address) where nbytes is the +number of bytes received and address is the address of the socket sending the +data. The format of address depends on the address family. For IP sockets, +address is a pair (hostaddr, port). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_recvfrom_into__doc__, +"recvfrom_into(buffer, nbytes=0, flags=0)\n" +"Receive data from the socket into the specified buffer.\n" +"\n" +" buffer\n" +" bytearray object to store data into.\n" +" nbytes\n" +" Maximum number of bytes to receive. Cannot be negative.\n" +" flags\n" +" See the Unix manual page recv(2) for info.\n" +"\n" +"If nbytes is not specified (or 0), receive up to the size available in the\n" +"given buffer. The return value is a pair (nbytes, address) where nbytes is the\n" +"number of bytes received and address is the address of the socket sending the\n" +"data. The format of address depends on the address family. For IP sockets,\n" +"address is a pair (hostaddr, port)."); + +#define _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF \ + {"recvfrom_into", (PyCFunction)_socket_socket_recvfrom_into, METH_VARARGS|METH_KEYWORDS, _socket_socket_recvfrom_into__doc__}, + +static PyObject * +_socket_socket_recvfrom_into_impl(PySocketSockObject *self, Py_buffer *buffer, Py_ssize_t nbytes, int flags); + +static PyObject * +_socket_socket_recvfrom_into(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"buffer", "nbytes", "flags", NULL}; + Py_buffer buffer = {NULL, NULL}; + Py_ssize_t nbytes = 0; int flags = 0; - Py_buffer pbuf; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "w*|ni:recvfrom_into", _keywords, + &buffer, &nbytes, &flags)) + goto exit; + return_value = _socket_socket_recvfrom_into_impl((PySocketSockObject *)self, &buffer, nbytes, flags); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) + PyBuffer_Release(&buffer); + + return return_value; +} + +static PyObject * +_socket_socket_recvfrom_into_impl(PySocketSockObject *self, Py_buffer *buffer, Py_ssize_t nbytes, int flags) +/*[clinic end generated code: checksum=6d27df506ffe7683a6c56da237e79be90d53bac4]*/ +{ char *buf; - Py_ssize_t readlen, buflen, recvlen = 0; - + Py_ssize_t buflen, readlen; PyObject *addr = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recvfrom_into", - kwlist, &pbuf, - &recvlen, &flags)) + buf = buffer->buf; + buflen = buffer->len; + + if (nbytes < 0) { + PyErr_SetString(PyExc_ValueError, + "negative nbytes"); return NULL; - buf = pbuf.buf; - buflen = pbuf.len; - - if (recvlen < 0) { - PyBuffer_Release(&pbuf); + } + if (nbytes == 0) { + /* If nbytes was not specified, use the buffer's length */ + nbytes = buflen; + } + /* Check if the buffer is large enough */ + if (buflen < nbytes ) { PyErr_SetString(PyExc_ValueError, - "negative buffersize in recvfrom_into"); + "buffer too small for requested bytes"); return NULL; } - if (recvlen == 0) { - /* If nbytes was not specified, use the buffer's length */ - recvlen = buflen; - } else if (recvlen > buflen) { - PyBuffer_Release(&pbuf); - PyErr_SetString(PyExc_ValueError, - "nbytes is greater than the length of the buffer"); - return NULL; - } - - readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr); + + readlen = sock_recvfrom_guts(self, buf, nbytes, flags, &addr); if (readlen < 0) { - PyBuffer_Release(&pbuf); /* Return an error */ Py_XDECREF(addr); return NULL; } - PyBuffer_Release(&pbuf); /* Return the number of bytes read and the address. Note that we do not do anything special here in the case that readlen < recvlen. */ return Py_BuildValue("nN", readlen, addr); } -PyDoc_STRVAR(recvfrom_into_doc, -"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\ -\n\ -Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info."); - /* The sendmsg() and recvmsg[_into]() methods require a working CMSG_LEN(). See the comment near get_CMSG_LEN(). */ @@ -3070,19 +3616,105 @@ return *buf; } -/* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */ - -static PyObject * -sock_recvmsg(PySocketSockObject *s, PyObject *args) -{ - Py_ssize_t bufsize, ancbufsize = 0; +/*[clinic input] +_socket.socket.recvmsg + + self: socket_obj + bufsize: Py_ssize_t + Maximum number of bytes to receive. Cannot be negative. + ancbufsize: Py_ssize_t = 0 + Size in bytes of ancillary data buffer. + flags: int = 0 + See the Unix manual page recv(2) for info. + / + +Receive normal data (up to bufsize bytes) and ancillary data from the socket. + +The ancbufsize argument sets the size in bytes of the internal buffer used to +receive the ancillary data; it defaults to 0, meaning that no ancillary data +will be received. Appropriate buffer sizes for ancillary data can be calculated +using CMSG_SPACE() or CMSG_LEN(), and items which do not fit into the buffer +might be truncated or discarded. The flags argument defaults to 0 and has the +same meaning as for recv(). + +The return value is a 4-tuple: (data, ancdata, msg_flags, address). The data +item is a bytes object holding the non-ancillary data received. The ancdata +item is a list of zero or more tuples (cmsg_level, cmsg_type, cmsg_data) +representing the ancillary data (control messages) received: cmsg_level and +cmsg_type are integers specifying the protocol level and protocol-specific type +respectively, and cmsg_data is a bytes object holding the associated data. The +msg_flags item is the bitwise OR of various flags indicating conditions on the +received message; see your system documentation for details. If the receiving +socket is unconnected, address is the address of the sending socket, if +available; otherwise, its value is unspecified. + +If recvmsg() raises an exception after the system call returns, it will first +attempt to close any file descriptors received via this mechanism. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_recvmsg__doc__, +"recvmsg(bufsize, ancbufsize=0, flags=0)\n" +"Receive normal data (up to bufsize bytes) and ancillary data from the socket.\n" +"\n" +" bufsize\n" +" Maximum number of bytes to receive. Cannot be negative.\n" +" ancbufsize\n" +" Size in bytes of ancillary data buffer.\n" +" flags\n" +" See the Unix manual page recv(2) for info.\n" +"\n" +"The ancbufsize argument sets the size in bytes of the internal buffer used to\n" +"receive the ancillary data; it defaults to 0, meaning that no ancillary data\n" +"will be received. Appropriate buffer sizes for ancillary data can be calculated\n" +"using CMSG_SPACE() or CMSG_LEN(), and items which do not fit into the buffer\n" +"might be truncated or discarded. The flags argument defaults to 0 and has the\n" +"same meaning as for recv().\n" +"\n" +"The return value is a 4-tuple: (data, ancdata, msg_flags, address). The data\n" +"item is a bytes object holding the non-ancillary data received. The ancdata\n" +"item is a list of zero or more tuples (cmsg_level, cmsg_type, cmsg_data)\n" +"representing the ancillary data (control messages) received: cmsg_level and\n" +"cmsg_type are integers specifying the protocol level and protocol-specific type\n" +"respectively, and cmsg_data is a bytes object holding the associated data. The\n" +"msg_flags item is the bitwise OR of various flags indicating conditions on the\n" +"received message; see your system documentation for details. If the receiving\n" +"socket is unconnected, address is the address of the sending socket, if\n" +"available; otherwise, its value is unspecified.\n" +"\n" +"If recvmsg() raises an exception after the system call returns, it will first\n" +"attempt to close any file descriptors received via this mechanism."); + +#define _SOCKET_SOCKET_RECVMSG_METHODDEF \ + {"recvmsg", (PyCFunction)_socket_socket_recvmsg, METH_VARARGS, _socket_socket_recvmsg__doc__}, + +static PyObject * +_socket_socket_recvmsg_impl(PySocketSockObject *self, Py_ssize_t bufsize, Py_ssize_t ancbufsize, int flags); + +static PyObject * +_socket_socket_recvmsg(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t bufsize; + Py_ssize_t ancbufsize = 0; int flags = 0; + + if (!PyArg_ParseTuple(args, + "n|ni:recvmsg", + &bufsize, &ancbufsize, &flags)) + goto exit; + return_value = _socket_socket_recvmsg_impl((PySocketSockObject *)self, bufsize, ancbufsize, flags); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_recvmsg_impl(PySocketSockObject *self, Py_ssize_t bufsize, Py_ssize_t ancbufsize, int flags) +/*[clinic end generated code: checksum=4ad6d355a6110f592902342fedb71390286fd05c]*/ +{ struct iovec iov; PyObject *buf = NULL, *retval = NULL; - if (!PyArg_ParseTuple(args, "n|ni:recvmsg", &bufsize, &ancbufsize, &flags)) - return NULL; - if (bufsize < 0) { PyErr_SetString(PyExc_ValueError, "negative buffer size in recvmsg()"); return NULL; @@ -3095,41 +3727,12 @@ /* Note that we're passing a pointer to *our pointer* to the bytes object here (&buf); makeval_recvmsg() may incref the object, or deallocate it and set our pointer to NULL. */ - retval = sock_recvmsg_guts(s, &iov, 1, flags, ancbufsize, + retval = sock_recvmsg_guts(self, &iov, 1, flags, ancbufsize, &makeval_recvmsg, &buf); Py_XDECREF(buf); return retval; } -PyDoc_STRVAR(recvmsg_doc, -"recvmsg(bufsize[, ancbufsize[, flags]]) -> (data, ancdata, msg_flags, address)\n\ -\n\ -Receive normal data (up to bufsize bytes) and ancillary data from the\n\ -socket. The ancbufsize argument sets the size in bytes of the\n\ -internal buffer used to receive the ancillary data; it defaults to 0,\n\ -meaning that no ancillary data will be received. Appropriate buffer\n\ -sizes for ancillary data can be calculated using CMSG_SPACE() or\n\ -CMSG_LEN(), and items which do not fit into the buffer might be\n\ -truncated or discarded. The flags argument defaults to 0 and has the\n\ -same meaning as for recv().\n\ -\n\ -The return value is a 4-tuple: (data, ancdata, msg_flags, address).\n\ -The data item is a bytes object holding the non-ancillary data\n\ -received. The ancdata item is a list of zero or more tuples\n\ -(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data\n\ -(control messages) received: cmsg_level and cmsg_type are integers\n\ -specifying the protocol level and protocol-specific type respectively,\n\ -and cmsg_data is a bytes object holding the associated data. The\n\ -msg_flags item is the bitwise OR of various flags indicating\n\ -conditions on the received message; see your system documentation for\n\ -details. If the receiving socket is unconnected, address is the\n\ -address of the sending socket, if available; otherwise, its value is\n\ -unspecified.\n\ -\n\ -If recvmsg() raises an exception after the system call returns, it\n\ -will first attempt to close any file descriptors received via the\n\ -SCM_RIGHTS mechanism."); - static PyObject * makeval_recvmsg_into(ssize_t received, void *data) @@ -3137,23 +3740,92 @@ return PyLong_FromSsize_t(received); } -/* s.recvmsg_into(buffers[, ancbufsize[, flags]]) method */ - -static PyObject * -sock_recvmsg_into(PySocketSockObject *s, PyObject *args) -{ +/*[clinic input] +_socket.socket.recvmsg_into + + self: socket_obj + buffers: object + Maximum number of bytes to receive. Cannot be negative. + ancbufsize: Py_ssize_t = 0 + Size in bytes of ancillary data buffer. + flags: int = 0 + See the Unix manual page recv(2) for info. + / + +Receive normal data and ancillary data from the socket. + +This method behaves as recvmsg() would, but scatters the non-ancillary data +into a series of buffers instead of returning a new bytes object. The buffers +argument must be an iterable of objects that export writable buffers (e.g. +bytearray objects); these will be filled with successive chunks of the +non-ancillary data until it has all been written or there are no more buffers. +The operating system may set a limit (sysconf() value SC_IOV_MAX) on the number +of buffers that can be used. The ancbufsize and flags arguments have the same +meaning as for recvmsg(). + +The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address), where +nbytes is the total number of bytes of non-ancillary data written into the +buffers, and ancdata, msg_flags and address are the same as for recvmsg(). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_recvmsg_into__doc__, +"recvmsg_into(buffers, ancbufsize=0, flags=0)\n" +"Receive normal data and ancillary data from the socket.\n" +"\n" +" buffers\n" +" Maximum number of bytes to receive. Cannot be negative.\n" +" ancbufsize\n" +" Size in bytes of ancillary data buffer.\n" +" flags\n" +" See the Unix manual page recv(2) for info.\n" +"\n" +"This method behaves as recvmsg() would, but scatters the non-ancillary data\n" +"into a series of buffers instead of returning a new bytes object. The buffers\n" +"argument must be an iterable of objects that export writable buffers (e.g.\n" +"bytearray objects); these will be filled with successive chunks of the\n" +"non-ancillary data until it has all been written or there are no more buffers.\n" +"The operating system may set a limit (sysconf() value SC_IOV_MAX) on the number\n" +"of buffers that can be used. The ancbufsize and flags arguments have the same\n" +"meaning as for recvmsg().\n" +"\n" +"The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address), where\n" +"nbytes is the total number of bytes of non-ancillary data written into the\n" +"buffers, and ancdata, msg_flags and address are the same as for recvmsg()."); + +#define _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF \ + {"recvmsg_into", (PyCFunction)_socket_socket_recvmsg_into, METH_VARARGS, _socket_socket_recvmsg_into__doc__}, + +static PyObject * +_socket_socket_recvmsg_into_impl(PySocketSockObject *self, PyObject *buffers, Py_ssize_t ancbufsize, int flags); + +static PyObject * +_socket_socket_recvmsg_into(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *buffers; Py_ssize_t ancbufsize = 0; int flags = 0; + + if (!PyArg_ParseTuple(args, + "O|ni:recvmsg_into", + &buffers, &ancbufsize, &flags)) + goto exit; + return_value = _socket_socket_recvmsg_into_impl((PySocketSockObject *)self, buffers, ancbufsize, flags); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_recvmsg_into_impl(PySocketSockObject *self, PyObject *buffers, Py_ssize_t ancbufsize, int flags) +/*[clinic end generated code: checksum=fd2222dab0b6e4e268ba17bff13b854b5ae70ce6]*/ +{ struct iovec *iovs = NULL; Py_ssize_t i, nitems, nbufs = 0; Py_buffer *bufs = NULL; - PyObject *buffers_arg, *fast, *retval = NULL; - - if (!PyArg_ParseTuple(args, "O|ni:recvmsg_into", - &buffers_arg, &ancbufsize, &flags)) - return NULL; - - if ((fast = PySequence_Fast(buffers_arg, + PyObject *fast, *retval = NULL; + + if ((fast = PySequence_Fast(buffers, "recvmsg_into() argument 1 must be an " "iterable")) == NULL) return NULL; @@ -3180,7 +3852,7 @@ iovs[nbufs].iov_len = bufs[nbufs].len; } - retval = sock_recvmsg_guts(s, iovs, nitems, flags, ancbufsize, + retval = sock_recvmsg_guts(self, iovs, nitems, flags, ancbufsize, &makeval_recvmsg_into, NULL); finally: for (i = 0; i < nbufs; i++) @@ -3190,132 +3862,184 @@ Py_DECREF(fast); return retval; } - -PyDoc_STRVAR(recvmsg_into_doc, -"recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)\n\ -\n\ -Receive normal data and ancillary data from the socket, scattering the\n\ -non-ancillary data into a series of buffers. The buffers argument\n\ -must be an iterable of objects that export writable buffers\n\ -(e.g. bytearray objects); these will be filled with successive chunks\n\ -of the non-ancillary data until it has all been written or there are\n\ -no more buffers. The ancbufsize argument sets the size in bytes of\n\ -the internal buffer used to receive the ancillary data; it defaults to\n\ -0, meaning that no ancillary data will be received. Appropriate\n\ -buffer sizes for ancillary data can be calculated using CMSG_SPACE()\n\ -or CMSG_LEN(), and items which do not fit into the buffer might be\n\ -truncated or discarded. The flags argument defaults to 0 and has the\n\ -same meaning as for recv().\n\ -\n\ -The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address).\n\ -The nbytes item is the total number of bytes of non-ancillary data\n\ -written into the buffers. The ancdata item is a list of zero or more\n\ -tuples (cmsg_level, cmsg_type, cmsg_data) representing the ancillary\n\ -data (control messages) received: cmsg_level and cmsg_type are\n\ -integers specifying the protocol level and protocol-specific type\n\ -respectively, and cmsg_data is a bytes object holding the associated\n\ -data. The msg_flags item is the bitwise OR of various flags\n\ -indicating conditions on the received message; see your system\n\ -documentation for details. If the receiving socket is unconnected,\n\ -address is the address of the sending socket, if available; otherwise,\n\ -its value is unspecified.\n\ -\n\ -If recvmsg_into() raises an exception after the system call returns,\n\ -it will first attempt to close any file descriptors received via the\n\ -SCM_RIGHTS mechanism."); #endif /* CMSG_LEN */ -/* s.send(data [,flags]) method */ - -static PyObject * -sock_send(PySocketSockObject *s, PyObject *args) -{ - char *buf; - Py_ssize_t len, n = -1; - int flags = 0, timeout; - Py_buffer pbuf; - - if (!PyArg_ParseTuple(args, "y*|i:send", &pbuf, &flags)) - return NULL; - - if (!IS_SELECTABLE(s)) { - PyBuffer_Release(&pbuf); +/*[clinic input] +_socket.socket.send + + self: socket_obj + bytes: Py_buffer + The data to send. + flags: int = 0 + See the Unix manual page send(2) for info. + / + +Send data to the socket. + +The socket must be connected to a remote socket. Returns the number of bytes +sent. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_send__doc__, +"send(bytes, flags=0)\n" +"Send data to the socket.\n" +"\n" +" bytes\n" +" The data to send.\n" +" flags\n" +" See the Unix manual page send(2) for info.\n" +"\n" +"The socket must be connected to a remote socket. Returns the number of bytes\n" +"sent."); + +#define _SOCKET_SOCKET_SEND_METHODDEF \ + {"send", (PyCFunction)_socket_socket_send, METH_VARARGS, _socket_socket_send__doc__}, + +static PyObject * +_socket_socket_send_impl(PySocketSockObject *self, Py_buffer *bytes, int flags); + +static PyObject * +_socket_socket_send(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer bytes = {NULL, NULL}; + int flags = 0; + + if (!PyArg_ParseTuple(args, + "y*|i:send", + &bytes, &flags)) + goto exit; + return_value = _socket_socket_send_impl((PySocketSockObject *)self, &bytes, flags); + +exit: + /* Cleanup for bytes */ + if (bytes.obj) + PyBuffer_Release(&bytes); + + return return_value; +} + +static PyObject * +_socket_socket_send_impl(PySocketSockObject *self, Py_buffer *bytes, int flags) +/*[clinic end generated code: checksum=9f36885e4849f9c9425325d5992f716a16b6a362]*/ +{ + Py_ssize_t sent = -1, len = bytes->len; + int timeout; + + if (!IS_SELECTABLE(self)) return select_error(); - } - buf = pbuf.buf; - len = pbuf.len; - - BEGIN_SELECT_LOOP(s) + + BEGIN_SELECT_LOOP(self) Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 1, interval); + timeout = internal_select_ex(self, 1, interval); if (!timeout) { #ifdef MS_WINDOWS if (len > INT_MAX) len = INT_MAX; - n = send(s->sock_fd, buf, (int)len, flags); + sent = send(self->sock_fd, bytes->buf, (int)len, flags); #else - n = send(s->sock_fd, buf, len, flags); + sent = send(self->sock_fd, bytes->buf, len, flags); #endif } Py_END_ALLOW_THREADS if (timeout == 1) { - PyBuffer_Release(&pbuf); PyErr_SetString(socket_timeout, "timed out"); return NULL; } - END_SELECT_LOOP(s) - - PyBuffer_Release(&pbuf); - if (n < 0) - return s->errorhandler(); - return PyLong_FromSsize_t(n); -} - -PyDoc_STRVAR(send_doc, -"send(data[, flags]) -> count\n\ -\n\ -Send a data string to the socket. For the optional flags\n\ -argument, see the Unix manual. Return the number of bytes\n\ -sent; this may be less than len(data) if the network is busy."); - - -/* s.sendall(data [,flags]) method */ - -static PyObject * -sock_sendall(PySocketSockObject *s, PyObject *args) -{ - char *buf; - Py_ssize_t len, n = -1; - int flags = 0, timeout, saved_errno; - Py_buffer pbuf; - - if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags)) - return NULL; - buf = pbuf.buf; - len = pbuf.len; - - if (!IS_SELECTABLE(s)) { - PyBuffer_Release(&pbuf); + END_SELECT_LOOP(self) + + if (sent < 0) + return self->errorhandler(); + return PyLong_FromSsize_t(sent); +} + + +/*[clinic input] +_socket.socket.sendall + + self: socket_obj + bytes: Py_buffer + The data to send. + flags: int = 0 + See the Unix manual page send(2) for info. + / + +Send data from bytes repeatedly until all data is sent. + +The socket must be connected to a remote socket. Unlike send(), this method +continues to send data from bytes until either all data has been sent or an +error occurs. None is returned on success. On error, an exception is raised, +and there is no way to determine how much data, if any, was successfully sent. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_sendall__doc__, +"sendall(bytes, flags=0)\n" +"Send data from bytes repeatedly until all data is sent.\n" +"\n" +" bytes\n" +" The data to send.\n" +" flags\n" +" See the Unix manual page send(2) for info.\n" +"\n" +"The socket must be connected to a remote socket. Unlike send(), this method\n" +"continues to send data from bytes until either all data has been sent or an\n" +"error occurs. None is returned on success. On error, an exception is raised,\n" +"and there is no way to determine how much data, if any, was successfully sent."); + +#define _SOCKET_SOCKET_SENDALL_METHODDEF \ + {"sendall", (PyCFunction)_socket_socket_sendall, METH_VARARGS, _socket_socket_sendall__doc__}, + +static PyObject * +_socket_socket_sendall_impl(PySocketSockObject *self, Py_buffer *bytes, int flags); + +static PyObject * +_socket_socket_sendall(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer bytes = {NULL, NULL}; + int flags = 0; + + if (!PyArg_ParseTuple(args, + "y*|i:sendall", + &bytes, &flags)) + goto exit; + return_value = _socket_socket_sendall_impl((PySocketSockObject *)self, &bytes, flags); + +exit: + /* Cleanup for bytes */ + if (bytes.obj) + PyBuffer_Release(&bytes); + + return return_value; +} + +static PyObject * +_socket_socket_sendall_impl(PySocketSockObject *self, Py_buffer *bytes, int flags) +/*[clinic end generated code: checksum=4d72d6db0aad263324ca7471519bb6646b1b72a7]*/ +{ + Py_ssize_t sent, len = bytes->len; + int timeout, saved_errno; + char *buf = bytes->buf; + + if (!IS_SELECTABLE(pending)) return select_error(); - } do { Py_BEGIN_ALLOW_THREADS - timeout = internal_select(s, 1); - n = -1; + timeout = internal_select(self, 1); + sent = -1; if (!timeout) { #ifdef MS_WINDOWS if (len > INT_MAX) len = INT_MAX; - n = send(s->sock_fd, buf, (int)len, flags); + sent = send(self->sock_fd, buf, (int)len, flags); #else - n = send(s->sock_fd, buf, len, flags); + sent = send(self->sock_fd, buf, len, flags); #endif } Py_END_ALLOW_THREADS if (timeout == 1) { - PyBuffer_Release(&pbuf); PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -3324,40 +4048,26 @@ /* We must run our signal handlers before looping again. send() can return a successful partial write when it is interrupted, so we can't restrict ourselves to EINTR. */ - if (PyErr_CheckSignals()) { - PyBuffer_Release(&pbuf); + if (PyErr_CheckSignals()) return NULL; - } - if (n < 0) { + if (sent < 0) { /* If interrupted, try again */ if (saved_errno == EINTR) continue; - else - break; + return self->errorhandler(); } - buf += n; - len -= n; + buf += sent; + len -= sent; } while (len > 0); - PyBuffer_Release(&pbuf); - - if (n < 0) - return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(sendall_doc, -"sendall(data[, flags])\n\ -\n\ -Send a data string to the socket. For the optional flags\n\ -argument, see the Unix manual. This calls send() repeatedly\n\ -until all data is sent. If an error occurs, it's impossible\n\ -to tell how much data has been sent."); - - -/* s.sendto(data, [flags,] sockaddr) method */ - +/* s.sendto(bytes, [flags,] address) method */ + +/* Argument Clinic does not currently support sendto's optional middle + * argument configuration. */ static PyObject * sock_sendto(PySocketSockObject *s, PyObject *args) { @@ -3429,19 +4139,95 @@ } PyDoc_STRVAR(sendto_doc, -"sendto(data[, flags], address) -> count\n\ +"sendto(bytes[, flags], address) -> count\n\ \n\ -Like send(data, flags) but allows specifying the destination address.\n\ +Like send(bytes, flags) but allows specifying the destination address.\n\ For IP sockets, the address is a pair (hostaddr, port)."); - /* The sendmsg() and recvmsg[_into]() methods require a working CMSG_LEN(). See the comment near get_CMSG_LEN(). */ + #ifdef CMSG_LEN -/* s.sendmsg(buffers[, ancdata[, flags[, address]]]) method */ - -static PyObject * -sock_sendmsg(PySocketSockObject *s, PyObject *args) +/*[clinic input] +_socket.socket.sendmsg + + self: socket_obj + buffers: object + Iterable of non-ancillary data to send. + ancdata: object = NULL + Iterable of tuples of ancillary data to send. + flags: int = 0 + See the Unix manual page send(2) for info. + address: object = NULL + Destination address for the message. + / + +Send normal and ancillary data to the socket. + +The buffers argument specifies the non-ancillary data as an iterable of +buffer-compatible objects (e.g. bytes objects), which are concatenated and +sent as a single message. The ancdata argument specifies the ancillary data +(control messages) as an iterable of zero or more tuples (cmsg_level, +cmsg_type, cmsg_data), where cmsg_level and cmsg_type are integers +specifying the protocol level and protocol-specific type respectively, and +cmsg_data is a buffer-compatible object holding the associated data. The +flags argument defaults to 0 and has the same meaning as for send(). If +address is supplied and not None, it sets a destination address for the +message. The return value is the number of bytes of non-ancillary data sent. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_sendmsg__doc__, +"sendmsg(buffers, ancdata=None, flags=0, address=None)\n" +"Send normal and ancillary data to the socket.\n" +"\n" +" buffers\n" +" Iterable of non-ancillary data to send.\n" +" ancdata\n" +" Iterable of tuples of ancillary data to send.\n" +" flags\n" +" See the Unix manual page send(2) for info.\n" +" address\n" +" Destination address for the message.\n" +"\n" +"The buffers argument specifies the non-ancillary data as an iterable of\n" +"buffer-compatible objects (e.g. bytes objects), which are concatenated and\n" +"sent as a single message. The ancdata argument specifies the ancillary data\n" +"(control messages) as an iterable of zero or more tuples (cmsg_level,\n" +"cmsg_type, cmsg_data), where cmsg_level and cmsg_type are integers\n" +"specifying the protocol level and protocol-specific type respectively, and\n" +"cmsg_data is a buffer-compatible object holding the associated data. The\n" +"flags argument defaults to 0 and has the same meaning as for send(). If\n" +"address is supplied and not None, it sets a destination address for the\n" +"message. The return value is the number of bytes of non-ancillary data sent."); + +#define _SOCKET_SOCKET_SENDMSG_METHODDEF \ + {"sendmsg", (PyCFunction)_socket_socket_sendmsg, METH_VARARGS, _socket_socket_sendmsg__doc__}, + +static PyObject * +_socket_socket_sendmsg_impl(PySocketSockObject *self, PyObject *buffers, PyObject *ancdata, int flags, PyObject *address); + +static PyObject * +_socket_socket_sendmsg(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *buffers; + PyObject *ancdata = NULL; + int flags = 0; + PyObject *address = NULL; + + if (!PyArg_ParseTuple(args, + "O|OiO:sendmsg", + &buffers, &ancdata, &flags, &address)) + goto exit; + return_value = _socket_socket_sendmsg_impl((PySocketSockObject *)self, buffers, ancdata, flags, address); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_sendmsg_impl(PySocketSockObject *self, PyObject *buffers, PyObject *ancdata, int flags, PyObject *address) +/*[clinic end generated code: checksum=9e5580bbcea5177a11fdd935f330b17f0cc54697]*/ { Py_ssize_t i, ndataparts, ndatabufs = 0, ncmsgs, ncmsgbufs = 0; Py_buffer *databufs = NULL; @@ -3456,17 +4242,12 @@ void *controlbuf = NULL; size_t controllen, controllen_last; ssize_t bytes_sent = -1; - int addrlen, timeout, flags = 0; - PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, *data_fast = NULL, - *cmsg_fast = NULL, *retval = NULL; - - if (!PyArg_ParseTuple(args, "O|OiO:sendmsg", - &data_arg, &cmsg_arg, &flags, &addr_arg)) - return NULL; + int addrlen, timeout; + PyObject *data_fast = NULL, *cmsg_fast = NULL, *retval = NULL; /* Parse destination address. */ - if (addr_arg != NULL && addr_arg != Py_None) { - if (!getsockaddrarg(s, addr_arg, SAS2SA(&addrbuf), &addrlen)) + if (address != NULL && address != Py_None) { + if (!getsockaddrarg(self, address, SAS2SA(&addrbuf), &addrlen)) goto finally; msg.msg_name = &addrbuf; msg.msg_namelen = addrlen; @@ -3474,7 +4255,7 @@ /* Fill in an iovec for each message part, and save the Py_buffer structs to release afterwards. */ - if ((data_fast = PySequence_Fast(data_arg, + if ((data_fast = PySequence_Fast(buffers, "sendmsg() argument 1 must be an " "iterable")) == NULL) goto finally; @@ -3500,10 +4281,10 @@ iovs[ndatabufs].iov_len = databufs[ndatabufs].len; } - if (cmsg_arg == NULL) + if (ancdata == NULL) ncmsgs = 0; else { - if ((cmsg_fast = PySequence_Fast(cmsg_arg, + if ((cmsg_fast = PySequence_Fast(ancdata, "sendmsg() argument 2 must be an " "iterable")) == NULL) goto finally; @@ -3607,25 +4388,25 @@ } /* Make the system call. */ - if (!IS_SELECTABLE(s)) { + if (!IS_SELECTABLE(self)) { select_error(); goto finally; } - BEGIN_SELECT_LOOP(s) + BEGIN_SELECT_LOOP(self) Py_BEGIN_ALLOW_THREADS; - timeout = internal_select_ex(s, 1, interval); + timeout = internal_select_ex(self, 1, interval); if (!timeout) - bytes_sent = sendmsg(s->sock_fd, &msg, flags); + bytes_sent = sendmsg(self->sock_fd, &msg, flags); Py_END_ALLOW_THREADS; if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); goto finally; } - END_SELECT_LOOP(s) + END_SELECT_LOOP(self) if (bytes_sent < 0) { - s->errorhandler(); + self->errorhandler(); goto finally; } retval = PyLong_FromSsize_t(bytes_sent); @@ -3644,52 +4425,71 @@ return retval; } -PyDoc_STRVAR(sendmsg_doc, -"sendmsg(buffers[, ancdata[, flags[, address]]]) -> count\n\ -\n\ -Send normal and ancillary data to the socket, gathering the\n\ -non-ancillary data from a series of buffers and concatenating it into\n\ -a single message. The buffers argument specifies the non-ancillary\n\ -data as an iterable of buffer-compatible objects (e.g. bytes objects).\n\ -The ancdata argument specifies the ancillary data (control messages)\n\ -as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n\ -cmsg_data), where cmsg_level and cmsg_type are integers specifying the\n\ -protocol level and protocol-specific type respectively, and cmsg_data\n\ -is a buffer-compatible object holding the associated data. The flags\n\ -argument defaults to 0 and has the same meaning as for send(). If\n\ -address is supplied and not None, it sets a destination address for\n\ -the message. The return value is the number of bytes of non-ancillary\n\ -data sent."); #endif /* CMSG_LEN */ -/* s.shutdown(how) method */ - -static PyObject * -sock_shutdown(PySocketSockObject *s, PyObject *arg) -{ +/*[clinic input] +_socket.socket.shutdown + + self: socket_obj + how: int + / + +Shut down one or both halves of the connection. + +If how is SHUT_RD, further receives are disallowed. If how is SHUT_WR, further +sends are disallowed. If how is SHUT_RDWR, further sends and receives are +disallowed. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_shutdown__doc__, +"shutdown(how)\n" +"Shut down one or both halves of the connection.\n" +"\n" +"If how is SHUT_RD, further receives are disallowed. If how is SHUT_WR, further\n" +"sends are disallowed. If how is SHUT_RDWR, further sends and receives are\n" +"disallowed."); + +#define _SOCKET_SOCKET_SHUTDOWN_METHODDEF \ + {"shutdown", (PyCFunction)_socket_socket_shutdown, METH_VARARGS, _socket_socket_shutdown__doc__}, + +static PyObject * +_socket_socket_shutdown_impl(PySocketSockObject *self, int how); + +static PyObject * +_socket_socket_shutdown(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; int how; + + if (!PyArg_ParseTuple(args, + "i:shutdown", + &how)) + goto exit; + return_value = _socket_socket_shutdown_impl((PySocketSockObject *)self, how); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_shutdown_impl(PySocketSockObject *self, int how) +/*[clinic end generated code: checksum=4de44ca3ad3ae2f23ba40e84610d60b4453ae030]*/ +{ int res; - how = _PyLong_AsInt(arg); - if (how == -1 && PyErr_Occurred()) - return NULL; Py_BEGIN_ALLOW_THREADS - res = shutdown(s->sock_fd, how); + res = shutdown(self->sock_fd, how); Py_END_ALLOW_THREADS if (res < 0) - return s->errorhandler(); + return self->errorhandler(); Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(shutdown_doc, -"shutdown(flag)\n\ -\n\ -Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\ -of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR)."); #if defined(MS_WINDOWS) && defined(SIO_RCVALL) +/* Argument Clinic does not support this style of argument parsing. */ static PyObject* sock_ioctl(PySocketSockObject *s, PyObject *arg) { @@ -3734,100 +4534,110 @@ #endif #if defined(MS_WINDOWS) -static PyObject* -sock_share(PySocketSockObject *s, PyObject *arg) +/*[clinic input] +_socket.socket.share + + self: socket_obj + process_id: DWORD + / + +Duplicate the socket and prepare it for sharing with a target process. + +The target process must be provided with process_id. The resulting bytes object +can then be passed to the target process using some form of interprocess +communication and the socket can be recreated there using fromshare(). Once +this method has been called, it is safe to close the socket since the operating +system has already duplicated it for the target process. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_socket_share__doc__, +"share(process_id)\n" +"Duplicate the socket and prepare it for sharing with a target process.\n" +"\n" +"The target process must be provided with process_id. The resulting bytes object\n" +"can then be passed to the target process using some form of interprocess\n" +"communication and the socket can be recreated there using fromshare(). Once\n" +"this method has been called, it is safe to close the socket since the operating\n" +"system has already duplicated it for the target process."); + +#define _SOCKET_SOCKET_SHARE_METHODDEF \ + {"share", (PyCFunction)_socket_socket_share, METH_VARARGS, _socket_socket_share__doc__}, + +static PyObject * +_socket_socket_share_impl(PySocketSockObject *self, DWORD process_id); + +static PyObject * +_socket_socket_share(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + DWORD process_id; + + if (!PyArg_ParseTuple(args, + "I:share", + &process_id)) + goto exit; + return_value = _socket_socket_share_impl((PySocketSockObject *)self, process_id); + +exit: + return return_value; +} + +static PyObject * +_socket_socket_share_impl(PySocketSockObject *self, DWORD process_id) +/*[clinic end generated code: checksum=a92842fe085ebbf6f005e8ed1d11a53c2d146d7f]*/ { WSAPROTOCOL_INFO info; - DWORD processId; int result; - if (!PyArg_ParseTuple(arg, "I", &processId)) - return NULL; - Py_BEGIN_ALLOW_THREADS - result = WSADuplicateSocket(s->sock_fd, processId, &info); + result = WSADuplicateSocket(s->sock_fd, process_id, &info); Py_END_ALLOW_THREADS if (result == SOCKET_ERROR) return set_error(); return PyBytes_FromStringAndSize((const char*)&info, sizeof(info)); } -PyDoc_STRVAR(sock_share_doc, -"share(process_id) -> bytes\n\ -\n\ -Share the socket with another process. The target process id\n\ -must be provided and the resulting bytes object passed to the target\n\ -process. There the shared socket can be instantiated by calling\n\ -socket.fromshare()."); - - #endif /* List of methods for socket objects */ static PyMethodDef sock_methods[] = { - {"_accept", (PyCFunction)sock_accept, METH_NOARGS, - accept_doc}, - {"bind", (PyCFunction)sock_bind, METH_O, - bind_doc}, - {"close", (PyCFunction)sock_close, METH_NOARGS, - close_doc}, - {"connect", (PyCFunction)sock_connect, METH_O, - connect_doc}, - {"connect_ex", (PyCFunction)sock_connect_ex, METH_O, - connect_ex_doc}, - {"detach", (PyCFunction)sock_detach, METH_NOARGS, - detach_doc}, - {"fileno", (PyCFunction)sock_fileno, METH_NOARGS, - fileno_doc}, + _SOCKET_SOCKET__ACCEPT_METHODDEF + _SOCKET_SOCKET_BIND_METHODDEF + _SOCKET_SOCKET_CLOSE_METHODDEF + _SOCKET_SOCKET_CONNECT_METHODDEF + _SOCKET_SOCKET_CONNECT_EX_METHODDEF + _SOCKET_SOCKET_DETACH_METHODDEF + _SOCKET_SOCKET_FILENO_METHODDEF #ifdef HAVE_GETPEERNAME - {"getpeername", (PyCFunction)sock_getpeername, - METH_NOARGS, getpeername_doc}, -#endif - {"getsockname", (PyCFunction)sock_getsockname, - METH_NOARGS, getsockname_doc}, - {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS, - getsockopt_doc}, + _SOCKET_SOCKET_GETPEERNAME_METHODDEF +#endif + _SOCKET_SOCKET_GETSOCKNAME_METHODDEF + _SOCKET_SOCKET_GETSOCKOPT_METHODDEF + _SOCKET_SOCKET_SETSOCKOPT_METHODDEF #if defined(MS_WINDOWS) && defined(SIO_RCVALL) {"ioctl", (PyCFunction)sock_ioctl, METH_VARARGS, sock_ioctl_doc}, #endif #if defined(MS_WINDOWS) - {"share", (PyCFunction)sock_share, METH_VARARGS, - sock_share_doc}, -#endif - {"listen", (PyCFunction)sock_listen, METH_O, - listen_doc}, - {"recv", (PyCFunction)sock_recv, METH_VARARGS, - recv_doc}, - {"recv_into", (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS, - recv_into_doc}, - {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS, - recvfrom_doc}, - {"recvfrom_into", (PyCFunction)sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS, - recvfrom_into_doc}, - {"send", (PyCFunction)sock_send, METH_VARARGS, - send_doc}, - {"sendall", (PyCFunction)sock_sendall, METH_VARARGS, - sendall_doc}, + _SOCKET_SOCKET_SHARE_METHODDEF +#endif + _SOCKET_SOCKET_LISTEN_METHODDEF + _SOCKET_SOCKET_RECV_METHODDEF + _SOCKET_SOCKET_RECV_INTO_METHODDEF + _SOCKET_SOCKET_RECVFROM_METHODDEF + _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF + _SOCKET_SOCKET_SEND_METHODDEF + _SOCKET_SOCKET_SENDALL_METHODDEF {"sendto", (PyCFunction)sock_sendto, METH_VARARGS, sendto_doc}, - {"setblocking", (PyCFunction)sock_setblocking, METH_O, - setblocking_doc}, - {"settimeout", (PyCFunction)sock_settimeout, METH_O, - settimeout_doc}, - {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS, - gettimeout_doc}, - {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS, - setsockopt_doc}, - {"shutdown", (PyCFunction)sock_shutdown, METH_O, - shutdown_doc}, + _SOCKET_SOCKET_SETBLOCKING_METHODDEF + _SOCKET_SOCKET_SETTIMEOUT_METHODDEF + _SOCKET_SOCKET_GETTIMEOUT_METHODDEF + _SOCKET_SOCKET_SHUTDOWN_METHODDEF #ifdef CMSG_LEN - {"recvmsg", (PyCFunction)sock_recvmsg, METH_VARARGS, - recvmsg_doc}, - {"recvmsg_into", (PyCFunction)sock_recvmsg_into, METH_VARARGS, - recvmsg_into_doc,}, - {"sendmsg", (PyCFunction)sock_sendmsg, METH_VARARGS, - sendmsg_doc}, + _SOCKET_SOCKET_RECVMSG_METHODDEF + _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF + _SOCKET_SOCKET_SENDMSG_METHODDEF #endif {NULL, NULL} /* sentinel */ }; @@ -3912,7 +4722,6 @@ static int sock_cloexec_works = -1; #endif -/*ARGSUSED*/ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) { @@ -4093,11 +4902,35 @@ }; -/* Python interface to gethostname(). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostname(PyObject *self, PyObject *unused) +/*[clinic input] +_socket.gethostname + +Return the current host name. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_gethostname__doc__, +"gethostname()\n" +"Return the current host name."); + +#define _SOCKET_GETHOSTNAME_METHODDEF \ + {"gethostname", (PyCFunction)_socket_gethostname, METH_NOARGS, _socket_gethostname__doc__}, + +static PyObject * +_socket_gethostname_impl(PyModuleDef *module); + +static PyObject * +_socket_gethostname(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_gethostname_impl(module); + + return return_value; +} + +static PyObject * +_socket_gethostname_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=5c8299fb7f1bd056cb518c9b5d8c6b09937bad08]*/ { #ifdef MS_WINDOWS /* Don't use winsock's gethostname, as this returns the ANSI @@ -4146,10 +4979,6 @@ #endif } -PyDoc_STRVAR(gethostname_doc, -"gethostname() -> string\n\ -\n\ -Return the current host name."); #ifdef HAVE_SETHOSTNAME PyDoc_STRVAR(sethostname_doc, @@ -4188,31 +5017,65 @@ } #endif -/* Python interface to gethostbyname(name). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostbyname(PyObject *self, PyObject *args) -{ - char *name; + +/*[clinic input] +_socket.gethostbyname + + hostname: idna_str + / + +Translate a host name to IPv4 address format. + +The IPv4 address is returned as a string, such as '100.50.200.5'. If the host +name is an IPv4 address itself it is returned unchanged. See gethostbyname_ex() +for a more complete interface. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_gethostbyname__doc__, +"gethostbyname(hostname)\n" +"Translate a host name to IPv4 address format.\n" +"\n" +"The IPv4 address is returned as a string, such as \'100.50.200.5\'. If the host\n" +"name is an IPv4 address itself it is returned unchanged. See gethostbyname_ex()\n" +"for a more complete interface."); + +#define _SOCKET_GETHOSTBYNAME_METHODDEF \ + {"gethostbyname", (PyCFunction)_socket_gethostbyname, METH_VARARGS, _socket_gethostbyname__doc__}, + +static PyObject * +_socket_gethostbyname_impl(PyModuleDef *module, char *hostname); + +static PyObject * +_socket_gethostbyname(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + char *hostname; + + if (!PyArg_ParseTuple(args, + "et:gethostbyname", + "idna", &hostname)) + goto exit; + return_value = _socket_gethostbyname_impl(module, hostname); + +exit: + return return_value; +} + +static PyObject * +_socket_gethostbyname_impl(PyModuleDef *module, char *hostname) +/*[clinic end generated code: checksum=0a59d158920b78754dc7c978d702395a16036d96]*/ +{ sock_addr_t addrbuf; PyObject *ret = NULL; - if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) - return NULL; - if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0) + if (setipaddr(hostname, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0) goto finally; ret = makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in)); finally: - PyMem_Free(name); + PyMem_Free(hostname); return ret; } -PyDoc_STRVAR(gethostbyname_doc, -"gethostbyname(host) -> address\n\ -\n\ -Return the IP address (a string of the form '255.255.255.255') for a host."); - /* Convenience function common to gethostbyname_ex and gethostbyaddr */ @@ -4341,13 +5204,57 @@ } -/* Python interface to gethostbyname_ex(name). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostbyname_ex(PyObject *self, PyObject *args) -{ - char *name; +/*[clinic input] +_socket.gethostbyname_ex + + hostname: idna_str + / + +Translate a host name to IPv4 address format, extended interface. + +Return a triple (hostname, aliaslist, ipaddrlist) where hostname is the primary +host name responding to the given ip_address, aliaslist is a (possibly empty) +list of alternative host names for the same address, and ipaddrlist is a list +of IPv4 addresses for the same interface on the same host (often but not always +a single address). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_gethostbyname_ex__doc__, +"gethostbyname_ex(hostname)\n" +"Translate a host name to IPv4 address format, extended interface.\n" +"\n" +"Return a triple (hostname, aliaslist, ipaddrlist) where hostname is the primary\n" +"host name responding to the given ip_address, aliaslist is a (possibly empty)\n" +"list of alternative host names for the same address, and ipaddrlist is a list\n" +"of IPv4 addresses for the same interface on the same host (often but not always\n" +"a single address)."); + +#define _SOCKET_GETHOSTBYNAME_EX_METHODDEF \ + {"gethostbyname_ex", (PyCFunction)_socket_gethostbyname_ex, METH_VARARGS, _socket_gethostbyname_ex__doc__}, + +static PyObject * +_socket_gethostbyname_ex_impl(PyModuleDef *module, char *hostname); + +static PyObject * +_socket_gethostbyname_ex(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + char *hostname; + + if (!PyArg_ParseTuple(args, + "et:gethostbyname_ex", + "idna", &hostname)) + goto exit; + return_value = _socket_gethostbyname_ex_impl(module, hostname); + +exit: + return return_value; +} + +static PyObject * +_socket_gethostbyname_ex_impl(PyModuleDef *module, char *hostname) +/*[clinic end generated code: checksum=f62eb2de32d504f6354782a5d19db93bb6b49f16]*/ +{ struct hostent *h; sock_addr_t addr; struct sockaddr *sa; @@ -4366,27 +5273,25 @@ #endif #endif /* HAVE_GETHOSTBYNAME_R */ - if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name)) - return NULL; - if (setipaddr(name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) + if (setipaddr(hostname, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) goto finally; Py_BEGIN_ALLOW_THREADS #ifdef HAVE_GETHOSTBYNAME_R #if defined(HAVE_GETHOSTBYNAME_R_6_ARG) - gethostbyname_r(name, &hp_allocated, buf, buf_len, + gethostbyname_r(hostname, &hp_allocated, buf, buf_len, &h, &errnop); #elif defined(HAVE_GETHOSTBYNAME_R_5_ARG) - h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop); + h = gethostbyname_r(hostname, &hp_allocated, buf, buf_len, &errnop); #else /* HAVE_GETHOSTBYNAME_R_3_ARG */ memset((void *) &data, '\0', sizeof(data)); - result = gethostbyname_r(name, &hp_allocated, &data); + result = gethostbyname_r(hostname, &hp_allocated, &data); h = (result != 0) ? NULL : &hp_allocated; #endif #else /* not HAVE_GETHOSTBYNAME_R */ #ifdef USE_GETHOSTBYNAME_LOCK PyThread_acquire_lock(netdb_lock, 1); #endif - h = gethostbyname(name); + h = gethostbyname(hostname); #endif /* HAVE_GETHOSTBYNAME_R */ Py_END_ALLOW_THREADS /* Some C libraries would require addr.__ss_family instead of @@ -4400,26 +5305,60 @@ PyThread_release_lock(netdb_lock); #endif finally: - PyMem_Free(name); + PyMem_Free(hostname); return ret; } -PyDoc_STRVAR(ghbn_ex_doc, -"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\ -\n\ -Return the true host name, a list of aliases, and a list of IP addresses,\n\ -for a host. The host argument is a string giving a host name or IP number."); - - -/* Python interface to gethostbyaddr(IP). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostbyaddr(PyObject *self, PyObject *args) + +/*[clinic input] +_socket.gethostbyaddr + + ip_address: idna_str + / + +Translate a host name to IPv4 address format. + +The IPv4 address is returned as a string, such as '100.50.200.5'. If the host +name is an IPv4 address itself it is returned unchanged. See gethostbyname_ex() +for a more complete interface. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_gethostbyaddr__doc__, +"gethostbyaddr(ip_address)\n" +"Translate a host name to IPv4 address format.\n" +"\n" +"The IPv4 address is returned as a string, such as \'100.50.200.5\'. If the host\n" +"name is an IPv4 address itself it is returned unchanged. See gethostbyname_ex()\n" +"for a more complete interface."); + +#define _SOCKET_GETHOSTBYADDR_METHODDEF \ + {"gethostbyaddr", (PyCFunction)_socket_gethostbyaddr, METH_VARARGS, _socket_gethostbyaddr__doc__}, + +static PyObject * +_socket_gethostbyaddr_impl(PyModuleDef *module, char *ip_address); + +static PyObject * +_socket_gethostbyaddr(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + char *ip_address; + + if (!PyArg_ParseTuple(args, + "et:gethostbyaddr", + "idna", &ip_address)) + goto exit; + return_value = _socket_gethostbyaddr_impl(module, ip_address); + +exit: + return return_value; +} + +static PyObject * +_socket_gethostbyaddr_impl(PyModuleDef *module, char *ip_address) +/*[clinic end generated code: checksum=a436170b179309026f3710ebf0d0487e62251fa4]*/ { sock_addr_t addr; struct sockaddr *sa = SAS2SA(&addr); - char *ip_num; struct hostent *h; PyObject *ret = NULL; #ifdef HAVE_GETHOSTBYNAME_R @@ -4443,10 +5382,8 @@ int al; int af; - if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num)) - return NULL; af = AF_UNSPEC; - if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) + if (setipaddr(ip_address, sa, sizeof(addr), af) < 0) goto finally; af = sa->sa_family; ap = NULL; @@ -4492,31 +5429,61 @@ PyThread_release_lock(netdb_lock); #endif finally: - PyMem_Free(ip_num); + PyMem_Free(ip_address); return ret; } -PyDoc_STRVAR(gethostbyaddr_doc, -"gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\ -\n\ -Return the true host name, a list of aliases, and a list of IP addresses,\n\ -for a host. The host argument is a string giving a host name or IP number."); - - -/* Python interface to getservbyname(name). - This only returns the port number, since the other info is already - known or not useful (like the list of aliases). */ - -/*ARGSUSED*/ -static PyObject * -socket_getservbyname(PyObject *self, PyObject *args) -{ - char *name, *proto=NULL; + +/*[clinic input] +_socket.getservbyname + + servicename: str + protocolname: str = NULL + / + +Translate an Internet service name and protocol name to its port number. + +The optional protocol name, if given, should be 'tcp' or 'udp', otherwise any +protocol will match. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_getservbyname__doc__, +"getservbyname(servicename, protocolname=None)\n" +"Translate an Internet service name and protocol name to its port number.\n" +"\n" +"The optional protocol name, if given, should be \'tcp\' or \'udp\', otherwise any\n" +"protocol will match."); + +#define _SOCKET_GETSERVBYNAME_METHODDEF \ + {"getservbyname", (PyCFunction)_socket_getservbyname, METH_VARARGS, _socket_getservbyname__doc__}, + +static PyObject * +_socket_getservbyname_impl(PyModuleDef *module, const char *servicename, const char *protocolname); + +static PyObject * +_socket_getservbyname(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *servicename; + const char *protocolname = NULL; + + if (!PyArg_ParseTuple(args, + "s|s:getservbyname", + &servicename, &protocolname)) + goto exit; + return_value = _socket_getservbyname_impl(module, servicename, protocolname); + +exit: + return return_value; +} + +static PyObject * +_socket_getservbyname_impl(PyModuleDef *module, const char *servicename, const char *protocolname) +/*[clinic end generated code: checksum=de81389b41df61ea5441a24840d72a9baeaf3229]*/ +{ struct servent *sp; - if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto)) - return NULL; Py_BEGIN_ALLOW_THREADS - sp = getservbyname(name, proto); + sp = getservbyname(servicename, protocolname); Py_END_ALLOW_THREADS if (sp == NULL) { PyErr_SetString(PyExc_OSError, "service/proto not found"); @@ -4525,27 +5492,55 @@ return PyLong_FromLong((long) ntohs(sp->s_port)); } -PyDoc_STRVAR(getservbyname_doc, -"getservbyname(servicename[, protocolname]) -> integer\n\ -\n\ -Return a port number from a service name and protocol name.\n\ -The optional protocol name, if given, should be 'tcp' or 'udp',\n\ -otherwise any protocol will match."); - - -/* Python interface to getservbyport(port). - This only returns the service name, since the other info is already - known or not useful (like the list of aliases). */ - -/*ARGSUSED*/ -static PyObject * -socket_getservbyport(PyObject *self, PyObject *args) -{ + +/*[clinic input] +_socket.getservbyport + + port: int + protocolname: str = NULL + / + +Translate an Internet port number and protocol name to its service name. + +The optional protocol name, if given, should be 'tcp' or 'udp', otherwise any +protocol will match. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_getservbyport__doc__, +"getservbyport(port, protocolname=None)\n" +"Translate an Internet port number and protocol name to its service name.\n" +"\n" +"The optional protocol name, if given, should be \'tcp\' or \'udp\', otherwise any\n" +"protocol will match."); + +#define _SOCKET_GETSERVBYPORT_METHODDEF \ + {"getservbyport", (PyCFunction)_socket_getservbyport, METH_VARARGS, _socket_getservbyport__doc__}, + +static PyObject * +_socket_getservbyport_impl(PyModuleDef *module, int port, const char *protocolname); + +static PyObject * +_socket_getservbyport(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int port; - char *proto=NULL; + const char *protocolname = NULL; + + if (!PyArg_ParseTuple(args, + "i|s:getservbyport", + &port, &protocolname)) + goto exit; + return_value = _socket_getservbyport_impl(module, port, protocolname); + +exit: + return return_value; +} + +static PyObject * +_socket_getservbyport_impl(PyModuleDef *module, int port, const char *protocolname) +/*[clinic end generated code: checksum=b43ca6297edf4d497bc29c6cecb914973a954bf0]*/ +{ struct servent *sp; - if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto)) - return NULL; if (port < 0 || port > 0xffff) { PyErr_SetString( PyExc_OverflowError, @@ -4553,7 +5548,7 @@ return NULL; } Py_BEGIN_ALLOW_THREADS - sp = getservbyport(htons((short)port), proto); + sp = getservbyport(htons((short)port), protocolname); Py_END_ALLOW_THREADS if (sp == NULL) { PyErr_SetString(PyExc_OSError, "port/proto not found"); @@ -4562,27 +5557,59 @@ return PyUnicode_FromString(sp->s_name); } -PyDoc_STRVAR(getservbyport_doc, -"getservbyport(port[, protocolname]) -> string\n\ -\n\ -Return the service name from a port number and protocol name.\n\ -The optional protocol name, if given, should be 'tcp' or 'udp',\n\ -otherwise any protocol will match."); - -/* Python interface to getprotobyname(name). - This only returns the protocol number, since the other info is - already known or not useful (like the list of aliases). */ - -/*ARGSUSED*/ -static PyObject * -socket_getprotobyname(PyObject *self, PyObject *args) -{ - char *name; + +/*[clinic input] +_socket.getprotobyname + + protocolname: str + / + +Return the protocol number for the named protocol. + +Returns a constant suitable for passing as the (optional) third argument to the +socket() function. This is usually only needed for sockets opened in "raw" mode +(SOCK_RAW); for the normal socket modes, the correct protocol is chosen +automatically if the protocol is omitted or zero. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_getprotobyname__doc__, +"getprotobyname(protocolname)\n" +"Return the protocol number for the named protocol.\n" +"\n" +"Returns a constant suitable for passing as the (optional) third argument to the\n" +"socket() function. This is usually only needed for sockets opened in \"raw\" mode\n" +"(SOCK_RAW); for the normal socket modes, the correct protocol is chosen\n" +"automatically if the protocol is omitted or zero."); + +#define _SOCKET_GETPROTOBYNAME_METHODDEF \ + {"getprotobyname", (PyCFunction)_socket_getprotobyname, METH_VARARGS, _socket_getprotobyname__doc__}, + +static PyObject * +_socket_getprotobyname_impl(PyModuleDef *module, const char *protocolname); + +static PyObject * +_socket_getprotobyname(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *protocolname; + + if (!PyArg_ParseTuple(args, + "s:getprotobyname", + &protocolname)) + goto exit; + return_value = _socket_getprotobyname_impl(module, protocolname); + +exit: + return return_value; +} + +static PyObject * +_socket_getprotobyname_impl(PyModuleDef *module, const char *protocolname) +/*[clinic end generated code: checksum=3888d727b3b8404255f7fbc1e1a047a3fec02582]*/ +{ struct protoent *sp; - if (!PyArg_ParseTuple(args, "s:getprotobyname", &name)) - return NULL; Py_BEGIN_ALLOW_THREADS - sp = getprotobyname(name); + sp = getprotobyname(protocolname); Py_END_ALLOW_THREADS if (sp == NULL) { PyErr_SetString(PyExc_OSError, "protocol not found"); @@ -4591,17 +5618,27 @@ return PyLong_FromLong((long) sp->p_proto); } -PyDoc_STRVAR(getprotobyname_doc, -"getprotobyname(name) -> integer\n\ -\n\ -Return the protocol number for the named protocol. (Rarely used.)"); - #ifndef NO_DUP -/* dup() function for socket fds */ - -static PyObject * -socket_dup(PyObject *self, PyObject *fdobj) +/*[clinic input] +_socket.dup + + fdobj: object + / + +Duplicate the given socket filedescriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_dup__doc__, +"dup(fdobj)\n" +"Duplicate the given socket filedescriptor."); + +#define _SOCKET_DUP_METHODDEF \ + {"dup", (PyCFunction)_socket_dup, METH_O, _socket_dup__doc__}, + +static PyObject * +_socket_dup(PyModuleDef *module, PyObject *fdobj) +/*[clinic end generated code: checksum=aea78ce1a69ff6fd730e24f5d5dd2a419eeb5490]*/ { SOCKET_T fd, newfd; PyObject *newfdobj; @@ -4640,12 +5677,6 @@ SOCKETCLOSE(newfd); return newfdobj; } - -PyDoc_STRVAR(dup_doc, -"dup(integer) -> integer\n\ -\n\ -Duplicate an integer socket file descriptor. This is like os.dup(), but for\n\ -sockets; on some platforms os.dup() won't work for socket file descriptors."); #endif @@ -4654,7 +5685,8 @@ Arguments as for socket() except the default family is AF_UNIX if defined on the platform; otherwise, the default is AF_INET. */ -/*ARGSUSED*/ +/* Argument Clinic does not handle a mutable default for the first + * parameter. */ static PyObject * socket_socketpair(PyObject *self, PyObject *args) { @@ -4740,129 +5772,274 @@ #endif /* HAVE_SOCKETPAIR */ -static PyObject * -socket_ntohs(PyObject *self, PyObject *args) -{ - int x1, x2; - - if (!PyArg_ParseTuple(args, "i:ntohs", &x1)) { - return NULL; - } - if (x1 < 0) { +/*[clinic input] +_socket.ntohs + + x: int + / + +Convert 16-bit positive integers from network to host byte order. + +On machines where the host byte order is the same as network byte order, this +is a no-op; otherwise, it performs a 2-byte swap operation. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_ntohs__doc__, +"ntohs(x)\n" +"Convert 16-bit positive integers from network to host byte order.\n" +"\n" +"On machines where the host byte order is the same as network byte order, this\n" +"is a no-op; otherwise, it performs a 2-byte swap operation."); + +#define _SOCKET_NTOHS_METHODDEF \ + {"ntohs", (PyCFunction)_socket_ntohs, METH_VARARGS, _socket_ntohs__doc__}, + +static PyObject * +_socket_ntohs_impl(PyModuleDef *module, int x); + +static PyObject * +_socket_ntohs(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int x; + + if (!PyArg_ParseTuple(args, + "i:ntohs", + &x)) + goto exit; + return_value = _socket_ntohs_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +_socket_ntohs_impl(PyModuleDef *module, int x) +/*[clinic end generated code: checksum=0034c5adefd4fd280a79dd3957f8b2ceeb4f3df8]*/ +{ + int y; + + if (x < 0) { PyErr_SetString(PyExc_OverflowError, "can't convert negative number to unsigned long"); return NULL; } - x2 = (unsigned int)ntohs((unsigned short)x1); - return PyLong_FromLong(x2); -} - -PyDoc_STRVAR(ntohs_doc, -"ntohs(integer) -> integer\n\ -\n\ -Convert a 16-bit integer from network to host byte order."); - - -static PyObject * -socket_ntohl(PyObject *self, PyObject *arg) -{ - unsigned long x; - - if (PyLong_Check(arg)) { - x = PyLong_AsUnsignedLong(arg); - if (x == (unsigned long) -1 && PyErr_Occurred()) + y = (unsigned int)ntohs((unsigned short)x); + return PyLong_FromLong(y); +} + + +/*[clinic input] +_socket.ntohl + + x: object + / + +Convert 32-bit positive integers from network to host byte order. + +On machines where the host byte order is the same as network byte order, this +is a no-op; otherwise, it performs a 4-byte swap operation. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_ntohl__doc__, +"ntohl(x)\n" +"Convert 32-bit positive integers from network to host byte order.\n" +"\n" +"On machines where the host byte order is the same as network byte order, this\n" +"is a no-op; otherwise, it performs a 4-byte swap operation."); + +#define _SOCKET_NTOHL_METHODDEF \ + {"ntohl", (PyCFunction)_socket_ntohl, METH_O, _socket_ntohl__doc__}, + +static PyObject * +_socket_ntohl(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: checksum=4608b8cc8732bdcd94e7714605fa06286ddcd26a]*/ +{ + unsigned long l; + + if (PyLong_Check(x)) { + l = PyLong_AsUnsignedLong(x); + if (l == (unsigned long) -1 && PyErr_Occurred()) return NULL; #if SIZEOF_LONG > 4 { unsigned long y; /* only want the trailing 32 bits */ - y = x & 0xFFFFFFFFUL; - if (y ^ x) + y = l & 0xFFFFFFFFUL; + if (y ^ l) return PyErr_Format(PyExc_OverflowError, "int larger than 32 bits"); - x = y; + l = y; } #endif } else return PyErr_Format(PyExc_TypeError, "expected int, %s found", - Py_TYPE(arg)->tp_name); - return PyLong_FromUnsignedLong(ntohl(x)); -} - -PyDoc_STRVAR(ntohl_doc, -"ntohl(integer) -> integer\n\ -\n\ -Convert a 32-bit integer from network to host byte order."); - - -static PyObject * -socket_htons(PyObject *self, PyObject *args) -{ - int x1, x2; - - if (!PyArg_ParseTuple(args, "i:htons", &x1)) { - return NULL; - } - if (x1 < 0) { + Py_TYPE(x)->tp_name); + return PyLong_FromUnsignedLong(ntohl(l)); +} + + +/*[clinic input] +_socket.htons + + x: int + / + +Convert 16-bit positive integers from host to network byte order. + +On machines where the network byte order is the same as host byte order, this +is a no-op; otherwise, it performs a 2-byte swap operation. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_htons__doc__, +"htons(x)\n" +"Convert 16-bit positive integers from host to network byte order.\n" +"\n" +"On machines where the network byte order is the same as host byte order, this\n" +"is a no-op; otherwise, it performs a 2-byte swap operation."); + +#define _SOCKET_HTONS_METHODDEF \ + {"htons", (PyCFunction)_socket_htons, METH_VARARGS, _socket_htons__doc__}, + +static PyObject * +_socket_htons_impl(PyModuleDef *module, int x); + +static PyObject * +_socket_htons(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int x; + + if (!PyArg_ParseTuple(args, + "i:htons", + &x)) + goto exit; + return_value = _socket_htons_impl(module, x); + +exit: + return return_value; +} + +static PyObject * +_socket_htons_impl(PyModuleDef *module, int x) +/*[clinic end generated code: checksum=c6ee72795fb298c02a8d998199b77200160971e7]*/ +{ + int y; + + if (x < 0) { PyErr_SetString(PyExc_OverflowError, "can't convert negative number to unsigned long"); return NULL; } - x2 = (unsigned int)htons((unsigned short)x1); - return PyLong_FromLong(x2); -} - -PyDoc_STRVAR(htons_doc, -"htons(integer) -> integer\n\ -\n\ -Convert a 16-bit integer from host to network byte order."); - - -static PyObject * -socket_htonl(PyObject *self, PyObject *arg) -{ - unsigned long x; - - if (PyLong_Check(arg)) { - x = PyLong_AsUnsignedLong(arg); - if (x == (unsigned long) -1 && PyErr_Occurred()) + y = (unsigned int)htons((unsigned short)x); + return PyLong_FromLong(y); +} + + +/*[clinic input] +_socket.htonl + + x: object + / + +Convert 32-bit positive integers from host to network byte order. + +On machines where the network byte order is the same as host byte order, this +is a no-op; otherwise, it performs a 4-byte swap operation. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_htonl__doc__, +"htonl(x)\n" +"Convert 32-bit positive integers from host to network byte order.\n" +"\n" +"On machines where the network byte order is the same as host byte order, this\n" +"is a no-op; otherwise, it performs a 4-byte swap operation."); + +#define _SOCKET_HTONL_METHODDEF \ + {"htonl", (PyCFunction)_socket_htonl, METH_O, _socket_htonl__doc__}, + +static PyObject * +_socket_htonl(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: checksum=762b96f7506f8ea6cbd2dfe6898e09e38dfdda04]*/ +{ + unsigned long l; + + if (PyLong_Check(x)) { + l = PyLong_AsUnsignedLong(x); + if (l == (unsigned long) -1 && PyErr_Occurred()) return NULL; #if SIZEOF_LONG > 4 { unsigned long y; /* only want the trailing 32 bits */ - y = x & 0xFFFFFFFFUL; - if (y ^ x) + y = l & 0xFFFFFFFFUL; + if (y ^ l) return PyErr_Format(PyExc_OverflowError, "int larger than 32 bits"); - x = y; + l = y; } #endif } else return PyErr_Format(PyExc_TypeError, "expected int, %s found", - Py_TYPE(arg)->tp_name); - return PyLong_FromUnsignedLong(htonl((unsigned long)x)); -} - -PyDoc_STRVAR(htonl_doc, -"htonl(integer) -> integer\n\ -\n\ -Convert a 32-bit integer from host to network byte order."); - -/* socket.inet_aton() and socket.inet_ntoa() functions. */ - -PyDoc_STRVAR(inet_aton_doc, -"inet_aton(string) -> bytes giving packed 32-bit IP representation\n\ -\n\ -Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\ -binary format used in low-level network functions."); - -static PyObject* -socket_inet_aton(PyObject *self, PyObject *args) + Py_TYPE(x)->tp_name); + return PyLong_FromUnsignedLong(htonl((unsigned long)l)); +} + + +/*[clinic input] +_socket.inet_aton + + ip_string: str + / + +Convert an IPv4 address string to 32-bit packed binary format. + +Converts ip_string from dotted-quad string format (for example, ‘123.45.67.89’) +to 32-bit packed binary format, as a bytes object four characters in length. +This is useful when conversing with a program that uses the standard C library +and needs objects of type struct in_addr, which is the C type for the 32-bit +packed binary this function returns. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_inet_aton__doc__, +"inet_aton(ip_string)\n" +"Convert an IPv4 address string to 32-bit packed binary format.\n" +"\n" +"Converts ip_string from dotted-quad string format (for example, ‘123.45.67.89’)\n" +"to 32-bit packed binary format, as a bytes object four characters in length.\n" +"This is useful when conversing with a program that uses the standard C library\n" +"and needs objects of type struct in_addr, which is the C type for the 32-bit\n" +"packed binary this function returns."); + +#define _SOCKET_INET_ATON_METHODDEF \ + {"inet_aton", (PyCFunction)_socket_inet_aton, METH_VARARGS, _socket_inet_aton__doc__}, + +static PyObject * +_socket_inet_aton_impl(PyModuleDef *module, const char *ip_string); + +static PyObject * +_socket_inet_aton(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *ip_string; + + if (!PyArg_ParseTuple(args, + "s:inet_aton", + &ip_string)) + goto exit; + return_value = _socket_inet_aton_impl(module, ip_string); + +exit: + return return_value; +} + +static PyObject * +_socket_inet_aton_impl(PyModuleDef *module, const char *ip_string) +/*[clinic end generated code: checksum=62094bd5443dd5abdc947022a9f45d0aa70fd515]*/ { #ifdef HAVE_INET_ATON struct in_addr buf; @@ -4875,18 +6052,13 @@ /* Have to use inet_addr() instead */ unsigned int packed_addr; #endif - char *ip_addr; - - if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr)) - return NULL; - #ifdef HAVE_INET_ATON #ifdef USE_INET_ATON_WEAKLINK if (inet_aton != NULL) { #endif - if (inet_aton(ip_addr, &buf)) + if (inet_aton(ip_string, &buf)) return PyBytes_FromStringAndSize((char *)(&buf), sizeof(buf)); @@ -4904,11 +6076,11 @@ /* special-case this address as inet_addr might return INADDR_NONE * for this */ - if (strcmp(ip_addr, "255.255.255.255") == 0) { + if (strcmp(ip_string, "255.255.255.255") == 0) { packed_addr = INADDR_BROADCAST; } else { - packed_addr = inet_addr(ip_addr); + packed_addr = inet_addr(ip_string); if (packed_addr == INADDR_NONE) { /* invalid address */ PyErr_SetString(PyExc_OSError, @@ -4926,69 +6098,146 @@ #endif } -PyDoc_STRVAR(inet_ntoa_doc, -"inet_ntoa(packed_ip) -> ip_address_string\n\ -\n\ -Convert an IP address from 32-bit packed binary format to string format"); - -static PyObject* -socket_inet_ntoa(PyObject *self, PyObject *args) -{ - char *packed_str; - int addr_len; + +/*[clinic input] +_socket.inet_ntoa + + packed_ip: str(types='bytes', length=True) + / + +Convert a 32-bit packed IPv4 address to its string representation. + +Converts packed_ip (a bytes object four characters in length) to its standard +dotted-quad string representation (for example, ‘123.45.67.89’). This is useful +when conversing with a program that uses the standard C library and needs +objects of type struct in_addr, which is the C type for the 32-bit packed +binary data this function takes as an argument. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_inet_ntoa__doc__, +"inet_ntoa(packed_ip)\n" +"Convert a 32-bit packed IPv4 address to its string representation.\n" +"\n" +"Converts packed_ip (a bytes object four characters in length) to its standard\n" +"dotted-quad string representation (for example, ‘123.45.67.89’). This is useful\n" +"when conversing with a program that uses the standard C library and needs\n" +"objects of type struct in_addr, which is the C type for the 32-bit packed\n" +"binary data this function takes as an argument."); + +#define _SOCKET_INET_NTOA_METHODDEF \ + {"inet_ntoa", (PyCFunction)_socket_inet_ntoa, METH_VARARGS, _socket_inet_ntoa__doc__}, + +static PyObject * +_socket_inet_ntoa_impl(PyModuleDef *module, const char *packed_ip, Py_ssize_clean_t packed_ip_length); + +static PyObject * +_socket_inet_ntoa(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *packed_ip; + Py_ssize_clean_t packed_ip_length; + + if (!PyArg_ParseTuple(args, + "y#:inet_ntoa", + &packed_ip, &packed_ip_length)) + goto exit; + return_value = _socket_inet_ntoa_impl(module, packed_ip, packed_ip_length); + +exit: + return return_value; +} + +static PyObject * +_socket_inet_ntoa_impl(PyModuleDef *module, const char *packed_ip, Py_ssize_clean_t packed_ip_length) +/*[clinic end generated code: checksum=1928c36f9ccc10c2d2af03d3238861c19faffa7a]*/ +{ struct in_addr packed_addr; - if (!PyArg_ParseTuple(args, "y#:inet_ntoa", &packed_str, &addr_len)) { - return NULL; - } - - if (addr_len != sizeof(packed_addr)) { + if (packed_ip_length != sizeof(packed_addr)) { PyErr_SetString(PyExc_OSError, "packed IP wrong length for inet_ntoa"); return NULL; } - memcpy(&packed_addr, packed_str, addr_len); + memcpy(&packed_addr, packed_ip, packed_ip_length); return PyUnicode_FromString(inet_ntoa(packed_addr)); } #if defined(HAVE_INET_PTON) || defined(MS_WINDOWS) - -PyDoc_STRVAR(inet_pton_doc, -"inet_pton(af, ip) -> packed IP address string\n\ -\n\ -Convert an IP address from string format to a packed string suitable\n\ -for use with low-level network functions."); - -#endif - +/*[clinic input] +_socket.inet_pton + + address_family: int + ip_string: str + / + +Convert an IP address from its string format to a packed, binary format. + +inet_pton() is useful when a library or network protocol calls for an object of +type struct in_addr (similar to inet_aton()) or struct in6_addr. Supported +values for address_family are currently AF_INET and AF_INET6. If the IP address +string ip_string is invalid, OSError will be raised. Note that exactly what is +valid depends on both the value of address_family and the underlying +implementation of inet_pton(). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_inet_pton__doc__, +"inet_pton(address_family, ip_string)\n" +"Convert an IP address from its string format to a packed, binary format.\n" +"\n" +"inet_pton() is useful when a library or network protocol calls for an object of\n" +"type struct in_addr (similar to inet_aton()) or struct in6_addr. Supported\n" +"values for address_family are currently AF_INET and AF_INET6. If the IP address\n" +"string ip_string is invalid, OSError will be raised. Note that exactly what is\n" +"valid depends on both the value of address_family and the underlying\n" +"implementation of inet_pton()."); + +#define _SOCKET_INET_PTON_METHODDEF \ + {"inet_pton", (PyCFunction)_socket_inet_pton, METH_VARARGS, _socket_inet_pton__doc__}, + +static PyObject * +_socket_inet_pton_impl(PyModuleDef *module, int address_family, const char *ip_string); + +static PyObject * +_socket_inet_pton(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int address_family; + const char *ip_string; + + if (!PyArg_ParseTuple(args, + "is:inet_pton", + &address_family, &ip_string)) + goto exit; + return_value = _socket_inet_pton_impl(module, address_family, ip_string); + +exit: + return return_value; +} + +static PyObject * +_socket_inet_pton_impl(PyModuleDef *module, int address_family, const char *ip_string) +/*[clinic end generated code: checksum=5d5fef1e7f92508a29fcd4577e5df67be2c6963e]*/ +#endif #ifdef HAVE_INET_PTON - -static PyObject * -socket_inet_pton(PyObject *self, PyObject *args) -{ - int af; - char* ip; +{ int retval; #ifdef ENABLE_IPV6 char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; #else char packed[sizeof(struct in_addr)]; #endif - if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) { - return NULL; - } #if !defined(ENABLE_IPV6) && defined(AF_INET6) - if(af == AF_INET6) { + if (address_family == AF_INET6) { PyErr_SetString(PyExc_OSError, "can't use AF_INET6, IPv6 is disabled"); return NULL; } #endif - retval = inet_pton(af, ip, packed); + retval = inet_pton(address_family, ip_string, packed); if (retval < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -4996,11 +6245,11 @@ PyErr_SetString(PyExc_OSError, "illegal IP address string passed to inet_pton"); return NULL; - } else if (af == AF_INET) { + } else if (address_family == AF_INET) { return PyBytes_FromStringAndSize(packed, sizeof(struct in_addr)); #ifdef ENABLE_IPV6 - } else if (af == AF_INET6) { + } else if (address_family == AF_INET6) { return PyBytes_FromStringAndSize(packed, sizeof(struct in6_addr)); #endif @@ -5010,30 +6259,21 @@ } } #elif defined(MS_WINDOWS) - -static PyObject * -socket_inet_pton(PyObject *self, PyObject *args) -{ - int af; - char* ip; +{ struct sockaddr_in6 addr; INT ret, size; - if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) { - return NULL; - } - size = sizeof(addr); - ret = WSAStringToAddressA(ip, af, NULL, (LPSOCKADDR)&addr, &size); + ret = WSAStringToAddressA(ip_string, address_family, NULL, (LPSOCKADDR)&addr, &size); if (ret) { PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); return NULL; - } else if(af == AF_INET) { + } else if (address_family == AF_INET) { struct sockaddr_in *addr4 = (struct sockaddr_in*)&addr; return PyBytes_FromStringAndSize((const char *)&(addr4->sin_addr), sizeof(addr4->sin_addr)); - } else if (af == AF_INET6) { + } else if (address_family == AF_INET6) { return PyBytes_FromStringAndSize((const char *)&(addr.sin6_addr), sizeof(addr.sin6_addr)); } else { @@ -5045,22 +6285,68 @@ #endif #if defined(HAVE_INET_PTON) || defined(MS_WINDOWS) - -PyDoc_STRVAR(inet_ntop_doc, -"inet_ntop(af, packed_ip) -> string formatted IP address\n\ -\n\ -Convert a packed IP address of the given family to string format."); - -#endif - - +/*[clinic input] +_socket.inet_ntop + + address_family: int + packed_ip: str(types='bytes', length=True) + / + +Convert an IP address from a packed, binary format to its string format. + +Converts packed_ip (a bytes object of some number of characters) to its +standard, family-specific string representation (for example, '7.10.0.5' or +'5aef:2b::8'). inet_ntop() is useful when a library or network protocol returns +an object of type struct in_addr (similar to inet_ntoa()) or struct in6_addr. +Supported values for address_family are currently AF_INET and AF_INET6. If the +string packed_ip is not the correct length for the specified address family, +ValueError will be raised. A OSError is raised for errors from the call to +inet_ntop(). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_inet_ntop__doc__, +"inet_ntop(address_family, packed_ip)\n" +"Convert an IP address from a packed, binary format to its string format.\n" +"\n" +"Converts packed_ip (a bytes object of some number of characters) to its\n" +"standard, family-specific string representation (for example, \'7.10.0.5\' or\n" +"\'5aef:2b::8\'). inet_ntop() is useful when a library or network protocol returns\n" +"an object of type struct in_addr (similar to inet_ntoa()) or struct in6_addr.\n" +"Supported values for address_family are currently AF_INET and AF_INET6. If the\n" +"string packed_ip is not the correct length for the specified address family,\n" +"ValueError will be raised. A OSError is raised for errors from the call to\n" +"inet_ntop()."); + +#define _SOCKET_INET_NTOP_METHODDEF \ + {"inet_ntop", (PyCFunction)_socket_inet_ntop, METH_VARARGS, _socket_inet_ntop__doc__}, + +static PyObject * +_socket_inet_ntop_impl(PyModuleDef *module, int address_family, const char *packed_ip, Py_ssize_clean_t packed_ip_length); + +static PyObject * +_socket_inet_ntop(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int address_family; + const char *packed_ip; + Py_ssize_clean_t packed_ip_length; + + if (!PyArg_ParseTuple(args, + "iy#:inet_ntop", + &address_family, &packed_ip, &packed_ip_length)) + goto exit; + return_value = _socket_inet_ntop_impl(module, address_family, packed_ip, packed_ip_length); + +exit: + return return_value; +} + +static PyObject * +_socket_inet_ntop_impl(PyModuleDef *module, int address_family, const char *packed_ip, Py_ssize_clean_t packed_ip_length) +/*[clinic end generated code: checksum=c7ba87e9bb863f149fc728443193e275bd532a47]*/ +#endif #ifdef HAVE_INET_PTON -static PyObject * -socket_inet_ntop(PyObject *self, PyObject *args) -{ - int af; - char* packed; - int len; +{ const char* retval; #ifdef ENABLE_IPV6 char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1]; @@ -5071,19 +6357,15 @@ /* Guarantee NUL-termination for PyUnicode_FromString() below */ memset((void *) &ip[0], '\0', sizeof(ip)); - if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) { - return NULL; - } - - if (af == AF_INET) { - if (len != sizeof(struct in_addr)) { + if (address_family == AF_INET) { + if (packed_ip_length != sizeof(struct in_addr)) { PyErr_SetString(PyExc_ValueError, "invalid length of packed IP address string"); return NULL; } #ifdef ENABLE_IPV6 - } else if (af == AF_INET6) { - if (len != sizeof(struct in6_addr)) { + } else if (address_family == AF_INET6) { + if (packed_ip_length != sizeof(struct in6_addr)) { PyErr_SetString(PyExc_ValueError, "invalid length of packed IP address string"); return NULL; @@ -5091,11 +6373,11 @@ #endif } else { PyErr_Format(PyExc_ValueError, - "unknown address family %d", af); + "unknown address family %d", address_family); return NULL; } - retval = inet_ntop(af, packed, ip, sizeof(ip)); + retval = inet_ntop(address_family, packed_ip, ip, sizeof(ip)); if (!retval) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -5107,15 +6389,8 @@ PyErr_SetString(PyExc_RuntimeError, "invalid handling of inet_ntop"); return NULL; } - #elif defined(MS_WINDOWS) - -static PyObject * -socket_inet_ntop(PyObject *self, PyObject *args) -{ - int af; - char* packed; - int len; +{ struct sockaddr_in6 addr; DWORD addrlen, ret, retlen; #ifdef ENABLE_IPV6 @@ -5127,24 +6402,20 @@ /* Guarantee NUL-termination for PyUnicode_FromString() below */ memset((void *) &ip[0], '\0', sizeof(ip)); - if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) { - return NULL; - } - - if (af == AF_INET) { + if (address_family == AF_INET) { struct sockaddr_in * addr4 = (struct sockaddr_in *)&addr; - if (len != sizeof(struct in_addr)) { + if (packed_ip_length != sizeof(struct in_addr)) { PyErr_SetString(PyExc_ValueError, "invalid length of packed IP address string"); return NULL; } memset(addr4, 0, sizeof(struct sockaddr_in)); addr4->sin_family = AF_INET; - memcpy(&(addr4->sin_addr), packed, sizeof(addr4->sin_addr)); + memcpy(&(addr4->sin_addr), packed_ip, sizeof(addr4->sin_addr)); addrlen = sizeof(struct sockaddr_in); - } else if (af == AF_INET6) { - if (len != sizeof(struct in6_addr)) { + } else if (address_family == AF_INET6) { + if (packed_ip_length != sizeof(struct in6_addr)) { PyErr_SetString(PyExc_ValueError, "invalid length of packed IP address string"); return NULL; @@ -5152,11 +6423,11 @@ memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; - memcpy(&(addr.sin6_addr), packed, sizeof(addr.sin6_addr)); + memcpy(&(addr.sin6_addr), packed_ip, sizeof(addr.sin6_addr)); addrlen = sizeof(addr); } else { PyErr_Format(PyExc_ValueError, - "unknown address family %d", af); + "unknown address family %d", address_family); return NULL; } @@ -5171,65 +6442,124 @@ return PyUnicode_FromString(ip); } } - #endif /* HAVE_INET_PTON */ -/* Python interface to getaddrinfo(host, port). */ - -/*ARGSUSED*/ -static PyObject * -socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) -{ - static char* kwnames[] = {"host", "port", "family", "type", "proto", - "flags", 0}; + +/*[clinic input] +_socket.getaddrinfo + + host: object + port: object + family: int(c_default='AF_UNSPEC') = 0 + type: int = 0 + proto: int = 0 + flags: int = 0 + +Resolve host and port into an addrinfo struct. + +The host argument is a domain name, a string representation of an IPv4/v6 +address or None. port is a string service name such as 'http', a numeric port +number or None. By passing None as the value of host and port, you can pass +NULL to the underlying C API. + +The family, type and proto arguments can be optionally specified in order to +narrow the list of addresses returned. Passing zero as a value for each of +these arguments selects the full range of results. The flags argument can be +one or several of the AI_* constants, and will influence how results are +computed and returned. + +The function returns a list of 5-tuples of the structure (family, type, proto, +canonname, sockaddr). +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_getaddrinfo__doc__, +"getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)\n" +"Resolve host and port into an addrinfo struct.\n" +"\n" +"The host argument is a domain name, a string representation of an IPv4/v6\n" +"address or None. port is a string service name such as \'http\', a numeric port\n" +"number or None. By passing None as the value of host and port, you can pass\n" +"NULL to the underlying C API.\n" +"\n" +"The family, type and proto arguments can be optionally specified in order to\n" +"narrow the list of addresses returned. Passing zero as a value for each of\n" +"these arguments selects the full range of results. The flags argument can be\n" +"one or several of the AI_* constants, and will influence how results are\n" +"computed and returned.\n" +"\n" +"The function returns a list of 5-tuples of the structure (family, type, proto,\n" +"canonname, sockaddr)."); + +#define _SOCKET_GETADDRINFO_METHODDEF \ + {"getaddrinfo", (PyCFunction)_socket_getaddrinfo, METH_VARARGS|METH_KEYWORDS, _socket_getaddrinfo__doc__}, + +static PyObject * +_socket_getaddrinfo_impl(PyModuleDef *module, PyObject *host, PyObject *port, int family, int type_value, int proto, int flags); + +static PyObject * +_socket_getaddrinfo(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"host", "port", "family", "type", "proto", "flags", NULL}; + PyObject *host; + PyObject *port; + int family = AF_UNSPEC; + int type_value = 0; + int proto = 0; + int flags = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OO|iiii:getaddrinfo", _keywords, + &host, &port, &family, &type_value, &proto, &flags)) + goto exit; + return_value = _socket_getaddrinfo_impl(module, host, port, family, type_value, proto, flags); + +exit: + return return_value; +} + +static PyObject * +_socket_getaddrinfo_impl(PyModuleDef *module, PyObject *host, PyObject *port, int family, int type_value, int proto, int flags) +/*[clinic end generated code: checksum=fa3d04f1633c0630578799a96078c276ade2bece]*/ +{ struct addrinfo hints, *res; struct addrinfo *res0 = NULL; - PyObject *hobj = NULL; - PyObject *pobj = (PyObject *)NULL; char pbuf[30]; char *hptr, *pptr; - int family, socktype, protocol, flags; int error; PyObject *all = (PyObject *)NULL; PyObject *idna = NULL; - socktype = protocol = flags = 0; - family = AF_UNSPEC; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo", - kwnames, &hobj, &pobj, &family, &socktype, - &protocol, &flags)) { - return NULL; - } - if (hobj == Py_None) { + if (host == Py_None) { hptr = NULL; - } else if (PyUnicode_Check(hobj)) { + } else if (PyUnicode_Check(host)) { _Py_IDENTIFIER(encode); - idna = _PyObject_CallMethodId(hobj, &PyId_encode, "s", "idna"); + idna = _PyObject_CallMethodId(host, &PyId_encode, "s", "idna"); if (!idna) return NULL; assert(PyBytes_Check(idna)); hptr = PyBytes_AS_STRING(idna); - } else if (PyBytes_Check(hobj)) { - hptr = PyBytes_AsString(hobj); + } else if (PyBytes_Check(host)) { + hptr = PyBytes_AsString(host); } else { PyErr_SetString(PyExc_TypeError, "getaddrinfo() argument 1 must be string or None"); return NULL; } - if (PyLong_CheckExact(pobj)) { - long value = PyLong_AsLong(pobj); + if (PyLong_CheckExact(port)) { + long value = PyLong_AsLong(port); if (value == -1 && PyErr_Occurred()) goto err; PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", value); pptr = pbuf; - } else if (PyUnicode_Check(pobj)) { - pptr = _PyUnicode_AsString(pobj); + } else if (PyUnicode_Check(port)) { + pptr = _PyUnicode_AsString(port); if (pptr == NULL) goto err; - } else if (PyBytes_Check(pobj)) { - pptr = PyBytes_AS_STRING(pobj); - } else if (pobj == Py_None) { + } else if (PyBytes_Check(port)) { + pptr = PyBytes_AS_STRING(port); + } else if (port == Py_None) { pptr = (char *)NULL; } else { PyErr_SetString(PyExc_OSError, "Int or String expected"); @@ -5246,8 +6576,8 @@ #endif memset(&hints, 0, sizeof(hints)); hints.ai_family = family; - hints.ai_socktype = socktype; - hints.ai_protocol = protocol; + hints.ai_socktype = type_value; + hints.ai_protocol = proto; hints.ai_flags = flags; Py_BEGIN_ALLOW_THREADS ACQUIRE_GETADDRINFO_LOCK @@ -5264,7 +6594,7 @@ for (res = res0; res; res = res->ai_next) { PyObject *single; PyObject *addr = - makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol); + makesockaddr(-1, res->ai_addr, res->ai_addrlen, proto); if (addr == NULL) goto err; single = Py_BuildValue("iiisO", res->ai_family, @@ -5291,20 +6621,56 @@ return (PyObject *)NULL; } -PyDoc_STRVAR(getaddrinfo_doc, -"getaddrinfo(host, port [, family, socktype, proto, flags])\n\ - -> list of (family, socktype, proto, canonname, sockaddr)\n\ -\n\ -Resolve host and port into addrinfo struct."); - -/* Python interface to getnameinfo(sa, flags). */ - -/*ARGSUSED*/ -static PyObject * -socket_getnameinfo(PyObject *self, PyObject *args) -{ - PyObject *sa = (PyObject *)NULL; + +/*[clinic input] +_socket.getnameinfo + + sockaddr: object + flags: int + / + +Translate a socket address sockaddr into a 2-tuple (host, port). + +Depending on the settings of flags, the result can contain a fully-qualified +domain name or numeric address representation in host. Similarly, port can +contain a string port name or a numeric port number. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_getnameinfo__doc__, +"getnameinfo(sockaddr, flags)\n" +"Translate a socket address sockaddr into a 2-tuple (host, port).\n" +"\n" +"Depending on the settings of flags, the result can contain a fully-qualified\n" +"domain name or numeric address representation in host. Similarly, port can\n" +"contain a string port name or a numeric port number."); + +#define _SOCKET_GETNAMEINFO_METHODDEF \ + {"getnameinfo", (PyCFunction)_socket_getnameinfo, METH_VARARGS, _socket_getnameinfo__doc__}, + +static PyObject * +_socket_getnameinfo_impl(PyModuleDef *module, PyObject *sockaddr, int flags); + +static PyObject * +_socket_getnameinfo(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sockaddr; int flags; + + if (!PyArg_ParseTuple(args, + "Oi:getnameinfo", + &sockaddr, &flags)) + goto exit; + return_value = _socket_getnameinfo_impl(module, sockaddr, flags); + +exit: + return return_value; +} + +static PyObject * +_socket_getnameinfo_impl(PyModuleDef *module, PyObject *sockaddr, int flags) +/*[clinic end generated code: checksum=e1dd2f2371f4ce8a9e47fe7c8e63dc91fac34e74]*/ +{ char *hostp; int port; unsigned int flowinfo, scope_id; @@ -5313,15 +6679,13 @@ int error; PyObject *ret = (PyObject *)NULL; - flags = flowinfo = scope_id = 0; - if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags)) - return NULL; - if (!PyTuple_Check(sa)) { + flowinfo = scope_id = 0; + if (!PyTuple_Check(sockaddr)) { PyErr_SetString(PyExc_TypeError, "getnameinfo() argument 1 must be a tuple"); return NULL; } - if (!PyArg_ParseTuple(sa, "si|II", + if (!PyArg_ParseTuple(sockaddr, "si|II", &hostp, &port, &flowinfo, &scope_id)) return NULL; if (flowinfo > 0xfffff) { @@ -5351,7 +6715,7 @@ switch (res->ai_family) { case AF_INET: { - if (PyTuple_GET_SIZE(sa) != 2) { + if (PyTuple_GET_SIZE(sockaddr) != 2) { PyErr_SetString(PyExc_OSError, "IPv4 sockaddr must be 2 tuple"); goto fail; @@ -5383,16 +6747,42 @@ return ret; } -PyDoc_STRVAR(getnameinfo_doc, -"getnameinfo(sockaddr, flags) --> (host, port)\n\ -\n\ -Get host and port for a sockaddr."); - - -/* Python API to getting and setting the default timeout value. */ - -static PyObject * -socket_getdefaulttimeout(PyObject *self) + +/*[clinic input] +_socket.getdefaulttimeout + +Return the default timeout in seconds (float) for new socket objects. + +A value of None indicates that new socket objects have no timeout. When the +socket module is first imported, the default is None. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_getdefaulttimeout__doc__, +"getdefaulttimeout()\n" +"Return the default timeout in seconds (float) for new socket objects.\n" +"\n" +"A value of None indicates that new socket objects have no timeout. When the\n" +"socket module is first imported, the default is None."); + +#define _SOCKET_GETDEFAULTTIMEOUT_METHODDEF \ + {"getdefaulttimeout", (PyCFunction)_socket_getdefaulttimeout, METH_NOARGS, _socket_getdefaulttimeout__doc__}, + +static PyObject * +_socket_getdefaulttimeout_impl(PyModuleDef *module); + +static PyObject * +_socket_getdefaulttimeout(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_getdefaulttimeout_impl(module); + + return return_value; +} + +static PyObject * +_socket_getdefaulttimeout_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=f38c1970938405fa7dbaedea2b183471e7ef52d1]*/ { if (defaulttimeout < 0.0) { Py_INCREF(Py_None); @@ -5402,23 +6792,44 @@ return PyFloat_FromDouble(defaulttimeout); } -PyDoc_STRVAR(getdefaulttimeout_doc, -"getdefaulttimeout() -> timeout\n\ -\n\ -Returns the default timeout in seconds (float) for new socket objects.\n\ -A value of None indicates that new socket objects have no timeout.\n\ -When the socket module is first imported, the default is None."); - -static PyObject * -socket_setdefaulttimeout(PyObject *self, PyObject *arg) -{ - double timeout; - - if (arg == Py_None) - timeout = -1.0; + +/*[clinic input] +_socket.setdefaulttimeout + + timeout: object + Default timeout as nonnegative float or None. + / + +Set the default timeout in seconds (float) for new socket objects. + +When the socket module is first imported, the default is None. See settimeout() +for possible values and their respective meanings. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_setdefaulttimeout__doc__, +"setdefaulttimeout(timeout)\n" +"Set the default timeout in seconds (float) for new socket objects.\n" +"\n" +" timeout\n" +" Default timeout as nonnegative float or None.\n" +"\n" +"When the socket module is first imported, the default is None. See settimeout()\n" +"for possible values and their respective meanings."); + +#define _SOCKET_SETDEFAULTTIMEOUT_METHODDEF \ + {"setdefaulttimeout", (PyCFunction)_socket_setdefaulttimeout, METH_O, _socket_setdefaulttimeout__doc__}, + +static PyObject * +_socket_setdefaulttimeout(PyModuleDef *module, PyObject *timeout) +/*[clinic end generated code: checksum=6966899fb020d4af132058e24fa147be09051958]*/ +{ + double c_timeout; + + if (timeout == Py_None) + c_timeout = -1.0; else { - timeout = PyFloat_AsDouble(arg); - if (timeout < 0.0) { + c_timeout = PyFloat_AsDouble(timeout); + if (c_timeout < 0.0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, "Timeout value out of range"); @@ -5426,24 +6837,49 @@ } } - defaulttimeout = timeout; + defaulttimeout = c_timeout; Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(setdefaulttimeout_doc, -"setdefaulttimeout(timeout)\n\ -\n\ -Set the default timeout in seconds (float) for new socket objects.\n\ -A value of None indicates that new socket objects have no timeout.\n\ -When the socket module is first imported, the default is None."); #ifdef HAVE_IF_NAMEINDEX -/* Python API for getting interface indices and names */ - -static PyObject * -socket_if_nameindex(PyObject *self, PyObject *arg) +/*[clinic input] +_socket.if_nameindex + +Retrieve network interface information. + +Returns a list of (index int, name string) tuples. Raises OSError if the system +call fails. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_if_nameindex__doc__, +"if_nameindex()\n" +"Retrieve network interface information.\n" +"\n" +"Returns a list of (index int, name string) tuples. Raises OSError if the system\n" +"call fails."); + +#define _SOCKET_IF_NAMEINDEX_METHODDEF \ + {"if_nameindex", (PyCFunction)_socket_if_nameindex, METH_NOARGS, _socket_if_nameindex__doc__}, + +static PyObject * +_socket_if_nameindex_impl(PyModuleDef *module); + +static PyObject * +_socket_if_nameindex(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + return_value = _socket_if_nameindex_impl(module); + + return return_value; +} + +static PyObject * +_socket_if_nameindex_impl(PyModuleDef *module) +/*[clinic end generated code: checksum=3161f3e56681e261ff9d5677216163a1183fc99d]*/ { PyObject *list; int i; @@ -5478,23 +6914,54 @@ return list; } -PyDoc_STRVAR(if_nameindex_doc, -"if_nameindex()\n\ -\n\ -Returns a list of network interface information (index, name) tuples."); - -static PyObject * -socket_if_nametoindex(PyObject *self, PyObject *args) -{ - PyObject *oname; + +/*[clinic input] +_socket.if_nametoindex + + if_name: object(converter='PyUnicode_FSConverter') + / + +Return a network interface index number corresponding to an interface name. + +Raises OSError if no interface with the given name exists. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_if_nametoindex__doc__, +"if_nametoindex(if_name)\n" +"Return a network interface index number corresponding to an interface name.\n" +"\n" +"Raises OSError if no interface with the given name exists."); + +#define _SOCKET_IF_NAMETOINDEX_METHODDEF \ + {"if_nametoindex", (PyCFunction)_socket_if_nametoindex, METH_VARARGS, _socket_if_nametoindex__doc__}, + +static PyObject * +_socket_if_nametoindex_impl(PyModuleDef *module, PyObject *if_name); + +static PyObject * +_socket_if_nametoindex(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *if_name; + + if (!PyArg_ParseTuple(args, + "O&:if_nametoindex", + PyUnicode_FSConverter, &if_name)) + goto exit; + return_value = _socket_if_nametoindex_impl(module, if_name); + +exit: + return return_value; +} + +static PyObject * +_socket_if_nametoindex_impl(PyModuleDef *module, PyObject *if_name) +/*[clinic end generated code: checksum=69cd0d851b9c1473dbda140ccf20ac49a851408e]*/ +{ unsigned long index; - if (!PyArg_ParseTuple(args, "O&:if_nametoindex", - PyUnicode_FSConverter, &oname)) - return NULL; - - index = if_nametoindex(PyBytes_AS_STRING(oname)); - Py_DECREF(oname); + index = if_nametoindex(PyBytes_AS_STRING(if_name)); + Py_DECREF(if_name); if (index == 0) { /* if_nametoindex() doesn't set errno */ PyErr_SetString(PyExc_OSError, "no interface with this name"); @@ -5504,18 +6971,35 @@ return PyLong_FromUnsignedLong(index); } -PyDoc_STRVAR(if_nametoindex_doc, -"if_nametoindex(if_name)\n\ -\n\ -Returns the interface index corresponding to the interface name if_name."); - -static PyObject * -socket_if_indextoname(PyObject *self, PyObject *arg) + +/*[clinic input] +_socket.if_indextoname + + if_index: object + / + +Return a network interface name corresponding to a interface index number. + +Raises OSError if no interface with the given index exists. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_if_indextoname__doc__, +"if_indextoname(if_index)\n" +"Return a network interface name corresponding to a interface index number.\n" +"\n" +"Raises OSError if no interface with the given index exists."); + +#define _SOCKET_IF_INDEXTONAME_METHODDEF \ + {"if_indextoname", (PyCFunction)_socket_if_indextoname, METH_O, _socket_if_indextoname__doc__}, + +static PyObject * +_socket_if_indextoname(PyModuleDef *module, PyObject *if_index) +/*[clinic end generated code: checksum=957ed44dd5f56536960e8963aa09414c064c6ffb]*/ { unsigned long index; char name[IF_NAMESIZE + 1]; - index = PyLong_AsUnsignedLong(arg); + index = PyLong_AsUnsignedLong(if_index); if (index == (unsigned long) -1) return NULL; @@ -5526,26 +7010,65 @@ return PyUnicode_DecodeFSDefault(name); } - -PyDoc_STRVAR(if_indextoname_doc, -"if_indextoname(if_index)\n\ -\n\ -Returns the interface name corresponding to the interface index if_index."); - #endif /* HAVE_IF_NAMEINDEX */ #ifdef CMSG_LEN -/* Python interface to CMSG_LEN(length). */ - -static PyObject * -socket_CMSG_LEN(PyObject *self, PyObject *args) -{ +/*[clinic input] +_socket.CMSG_LEN + + length: Py_ssize_t + / + +Return the total length of an ancillary data item. + +Returns the total length, without trailing padding, of an ancillary data item +with associated data of the given length. This value can often be used as the +buffer size for recvmsg() to receive a single item of ancillary data, but RFC +3542 requires portable applications to use CMSG_SPACE() and thus include space +for padding, even when the item will be the last in the buffer. Raises +OverflowError if length is outside the permissible range of values. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_CMSG_LEN__doc__, +"CMSG_LEN(length)\n" +"Return the total length of an ancillary data item.\n" +"\n" +"Returns the total length, without trailing padding, of an ancillary data item\n" +"with associated data of the given length. This value can often be used as the\n" +"buffer size for recvmsg() to receive a single item of ancillary data, but RFC\n" +"3542 requires portable applications to use CMSG_SPACE() and thus include space\n" +"for padding, even when the item will be the last in the buffer. Raises\n" +"OverflowError if length is outside the permissible range of values."); + +#define _SOCKET_CMSG_LEN_METHODDEF \ + {"CMSG_LEN", (PyCFunction)_socket_CMSG_LEN, METH_VARARGS, _socket_CMSG_LEN__doc__}, + +static PyObject * +_socket_CMSG_LEN_impl(PyModuleDef *module, Py_ssize_t length); + +static PyObject * +_socket_CMSG_LEN(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; Py_ssize_t length; + + if (!PyArg_ParseTuple(args, + "n:CMSG_LEN", + &length)) + goto exit; + return_value = _socket_CMSG_LEN_impl(module, length); + +exit: + return return_value; +} + +static PyObject * +_socket_CMSG_LEN_impl(PyModuleDef *module, Py_ssize_t length) +/*[clinic end generated code: checksum=36421b8e0bc89fc3c495a8720c7554c7dc29f4b9]*/ +{ size_t result; - if (!PyArg_ParseTuple(args, "n:CMSG_LEN", &length)) - return NULL; if (length < 0 || !get_CMSG_LEN(length, &result)) { PyErr_Format(PyExc_OverflowError, "CMSG_LEN() argument out of range"); return NULL; @@ -5553,29 +7076,71 @@ return PyLong_FromSize_t(result); } -PyDoc_STRVAR(CMSG_LEN_doc, -"CMSG_LEN(length) -> control message length\n\ -\n\ -Return the total length, without trailing padding, of an ancillary\n\ -data item with associated data of the given length. This value can\n\ -often be used as the buffer size for recvmsg() to receive a single\n\ -item of ancillary data, but RFC 3542 requires portable applications to\n\ -use CMSG_SPACE() and thus include space for padding, even when the\n\ -item will be the last in the buffer. Raises OverflowError if length\n\ -is outside the permissible range of values."); - #ifdef CMSG_SPACE -/* Python interface to CMSG_SPACE(length). */ - -static PyObject * -socket_CMSG_SPACE(PyObject *self, PyObject *args) -{ +/*[clinic input] +_socket.CMSG_SPACE + + length: Py_ssize_t + / + +Return the buffer size needed to receive an ancillary data item. + +Returns the buffer size needed for recvmsg() to receive an ancillary data item +with associated data of the given length, along with any trailing padding. The +buffer space needed to receive multiple items is the sum of the CMSG_SPACE() +values for their associated data lengths. Raises OverflowError if length is +outside the permissible range of values. + +Note that some systems might support ancillary data without providing this +function. Also note that setting the buffer size using the results of this +function may not precisely limit the amount of ancillary data that can be +received, since additional data may be able to fit into the padding area. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_CMSG_SPACE__doc__, +"CMSG_SPACE(length)\n" +"Return the buffer size needed to receive an ancillary data item.\n" +"\n" +"Returns the buffer size needed for recvmsg() to receive an ancillary data item\n" +"with associated data of the given length, along with any trailing padding. The\n" +"buffer space needed to receive multiple items is the sum of the CMSG_SPACE()\n" +"values for their associated data lengths. Raises OverflowError if length is\n" +"outside the permissible range of values.\n" +"\n" +"Note that some systems might support ancillary data without providing this\n" +"function. Also note that setting the buffer size using the results of this\n" +"function may not precisely limit the amount of ancillary data that can be\n" +"received, since additional data may be able to fit into the padding area."); + +#define _SOCKET_CMSG_SPACE_METHODDEF \ + {"CMSG_SPACE", (PyCFunction)_socket_CMSG_SPACE, METH_VARARGS, _socket_CMSG_SPACE__doc__}, + +static PyObject * +_socket_CMSG_SPACE_impl(PyModuleDef *module, Py_ssize_t length); + +static PyObject * +_socket_CMSG_SPACE(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; Py_ssize_t length; + + if (!PyArg_ParseTuple(args, + "n:CMSG_SPACE", + &length)) + goto exit; + return_value = _socket_CMSG_SPACE_impl(module, length); + +exit: + return return_value; +} + +static PyObject * +_socket_CMSG_SPACE_impl(PyModuleDef *module, Py_ssize_t length) +/*[clinic end generated code: checksum=c7548dbe353c00e313785946fe215066023b25b5]*/ +{ size_t result; - if (!PyArg_ParseTuple(args, "n:CMSG_SPACE", &length)) - return NULL; if (length < 0 || !get_CMSG_SPACE(length, &result)) { PyErr_SetString(PyExc_OverflowError, "CMSG_SPACE() argument out of range"); @@ -5583,16 +7148,6 @@ } return PyLong_FromSize_t(result); } - -PyDoc_STRVAR(CMSG_SPACE_doc, -"CMSG_SPACE(length) -> buffer size\n\ -\n\ -Return the buffer size needed for recvmsg() to receive an ancillary\n\ -data item with associated data of the given length, along with any\n\ -trailing padding. The buffer space needed to receive multiple items\n\ -is the sum of the CMSG_SPACE() values for their associated data\n\ -lengths. Raises OverflowError if length is outside the permissible\n\ -range of values."); #endif /* CMSG_SPACE */ #endif /* CMSG_LEN */ @@ -5600,72 +7155,47 @@ /* List of functions exported by this module. */ static PyMethodDef socket_methods[] = { - {"gethostbyname", socket_gethostbyname, - METH_VARARGS, gethostbyname_doc}, - {"gethostbyname_ex", socket_gethostbyname_ex, - METH_VARARGS, ghbn_ex_doc}, - {"gethostbyaddr", socket_gethostbyaddr, - METH_VARARGS, gethostbyaddr_doc}, - {"gethostname", socket_gethostname, - METH_NOARGS, gethostname_doc}, + _SOCKET_GETHOSTBYNAME_METHODDEF + _SOCKET_GETHOSTBYNAME_EX_METHODDEF + _SOCKET_GETHOSTBYADDR_METHODDEF + _SOCKET_GETHOSTNAME_METHODDEF #ifdef HAVE_SETHOSTNAME {"sethostname", socket_sethostname, METH_VARARGS, sethostname_doc}, #endif - {"getservbyname", socket_getservbyname, - METH_VARARGS, getservbyname_doc}, - {"getservbyport", socket_getservbyport, - METH_VARARGS, getservbyport_doc}, - {"getprotobyname", socket_getprotobyname, - METH_VARARGS, getprotobyname_doc}, + _SOCKET_GETSERVBYNAME_METHODDEF + _SOCKET_GETSERVBYPORT_METHODDEF + _SOCKET_GETPROTOBYNAME_METHODDEF #ifndef NO_DUP - {"dup", socket_dup, - METH_O, dup_doc}, + _SOCKET_DUP_METHODDEF #endif #ifdef HAVE_SOCKETPAIR {"socketpair", socket_socketpair, METH_VARARGS, socketpair_doc}, #endif - {"ntohs", socket_ntohs, - METH_VARARGS, ntohs_doc}, - {"ntohl", socket_ntohl, - METH_O, ntohl_doc}, - {"htons", socket_htons, - METH_VARARGS, htons_doc}, - {"htonl", socket_htonl, - METH_O, htonl_doc}, - {"inet_aton", socket_inet_aton, - METH_VARARGS, inet_aton_doc}, - {"inet_ntoa", socket_inet_ntoa, - METH_VARARGS, inet_ntoa_doc}, + _SOCKET_NTOHS_METHODDEF + _SOCKET_NTOHL_METHODDEF + _SOCKET_HTONS_METHODDEF + _SOCKET_HTONL_METHODDEF + _SOCKET_INET_ATON_METHODDEF + _SOCKET_INET_NTOA_METHODDEF #if defined(HAVE_INET_PTON) || defined(MS_WINDOWS) - {"inet_pton", socket_inet_pton, - METH_VARARGS, inet_pton_doc}, - {"inet_ntop", socket_inet_ntop, - METH_VARARGS, inet_ntop_doc}, -#endif - {"getaddrinfo", (PyCFunction)socket_getaddrinfo, - METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc}, - {"getnameinfo", socket_getnameinfo, - METH_VARARGS, getnameinfo_doc}, - {"getdefaulttimeout", (PyCFunction)socket_getdefaulttimeout, - METH_NOARGS, getdefaulttimeout_doc}, - {"setdefaulttimeout", socket_setdefaulttimeout, - METH_O, setdefaulttimeout_doc}, + _SOCKET_INET_PTON_METHODDEF + _SOCKET_INET_NTOP_METHODDEF +#endif + _SOCKET_GETADDRINFO_METHODDEF + _SOCKET_GETNAMEINFO_METHODDEF + _SOCKET_GETDEFAULTTIMEOUT_METHODDEF + _SOCKET_SETDEFAULTTIMEOUT_METHODDEF #ifdef HAVE_IF_NAMEINDEX - {"if_nameindex", socket_if_nameindex, - METH_NOARGS, if_nameindex_doc}, - {"if_nametoindex", socket_if_nametoindex, - METH_VARARGS, if_nametoindex_doc}, - {"if_indextoname", socket_if_indextoname, - METH_O, if_indextoname_doc}, + _SOCKET_IF_NAMEINDEX_METHODDEF + _SOCKET_IF_NAMETOINDEX_METHODDEF + _SOCKET_IF_INDEXTONAME_METHODDEF #endif #ifdef CMSG_LEN - {"CMSG_LEN", socket_CMSG_LEN, - METH_VARARGS, CMSG_LEN_doc}, + _SOCKET_CMSG_LEN_METHODDEF #ifdef CMSG_SPACE - {"CMSG_SPACE", socket_CMSG_SPACE, - METH_VARARGS, CMSG_SPACE_doc}, + _SOCKET_CMSG_SPACE_METHODDEF #endif #endif {NULL, NULL} /* Sentinel */