diff -r 1f4b0b886a25 -r bfe776417730 Modules/socketmodule.c --- a/Modules/socketmodule.c Tue Jan 14 18:14:05 2014 -0800 +++ b/Modules/socketmodule.c Wed Jan 15 17:36:25 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,229 @@ } } - 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\n" +"constants (SO_* etc.) are defined in this module. If buflen is absent, an\n" +"integer option is assumed and its integer value is returned by the function. If\n" +"buflen is present, it specifies the maximum length of the buffer used to\n" +"receive the option in, and this buffer is returned as a bytes object. It is up\n" +"to the caller to decode the contents of the buffer (see the optional built-in\n" +"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=3cfbccf23a72572bca8cb755fbc1d660b2eaea87]*/ +{ 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 +2399,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 +2497,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 +2633,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 +2677,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 +2736,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 +3008,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 +3094,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 +3257,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 +3352,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 +3628,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 +3739,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 +3752,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 +3864,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 +3874,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 +4060,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 +4151,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 +4254,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 +4267,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 +4293,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 +4400,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 +4437,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 +4546,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 +4734,6 @@ static int sock_cloexec_works = -1; #endif -/*ARGSUSED*/ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) { @@ -4093,11 +4914,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 +4991,6 @@ #endif } -PyDoc_STRVAR(gethostname_doc, -"gethostname() -> string\n\ -\n\ -Return the current host name."); #ifdef HAVE_SETHOSTNAME PyDoc_STRVAR(sethostname_doc, @@ -4188,31 +5029,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 +5216,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 +5285,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 +5317,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 +5394,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 +5441,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 +5504,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 +5560,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 +5569,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 +5630,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 file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(_socket_dup__doc__, +"dup(fdobj)\n" +"Duplicate the given socket file descriptor."); + +#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=3fb0aa66cafba4eb0d246a38256ee09b36847cda]*/ { SOCKET_T fd, newfd; PyObject *newfdobj; @@ -4640,12 +5689,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 +5697,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 +5784,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 +6064,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 +6088,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 +6110,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 +6257,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 +6271,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 +6297,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 +6369,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 +6385,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 +6401,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 +6414,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 +6435,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 +6454,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 +6588,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 +6606,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 +6633,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 +6691,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 +6727,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 +6759,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 +6804,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 +6849,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 +6926,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 +6983,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 +7022,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 +7088,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 +7160,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 +7167,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 */