diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 6df1c01f151f68e..c982f76431c52d1 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -1596,6 +1596,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(asend)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(assoclen)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ast)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(athrow)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(attr)); @@ -1811,6 +1812,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(headers)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hi)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(host)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hour)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hours)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(id)); @@ -1859,6 +1861,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iter)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterable)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterations)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iv)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(join)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(jump)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keepends)); @@ -1937,6 +1940,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespace_separator)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespaces)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(native)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nbytes)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ndigits)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nested)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_file_name)); @@ -1961,6 +1965,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(onceregistry)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(only_active_thread)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(only_keys)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(op)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(oparg)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opcode)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opcodes)); @@ -1995,6 +2000,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pidfd)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pointer_bits)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(policy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(port)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 873344fbdcb67b0..c430d0fb99bc41d 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -319,6 +319,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(argv) STRUCT_FOR_ID(as_integer_ratio) STRUCT_FOR_ID(asend) + STRUCT_FOR_ID(assoclen) STRUCT_FOR_ID(ast) STRUCT_FOR_ID(athrow) STRUCT_FOR_ID(attr) @@ -534,6 +535,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(headers) STRUCT_FOR_ID(hi) STRUCT_FOR_ID(hook) + STRUCT_FOR_ID(host) STRUCT_FOR_ID(hour) STRUCT_FOR_ID(hours) STRUCT_FOR_ID(id) @@ -582,6 +584,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(iter) STRUCT_FOR_ID(iterable) STRUCT_FOR_ID(iterations) + STRUCT_FOR_ID(iv) STRUCT_FOR_ID(join) STRUCT_FOR_ID(jump) STRUCT_FOR_ID(keepends) @@ -660,6 +663,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(namespace_separator) STRUCT_FOR_ID(namespaces) STRUCT_FOR_ID(native) + STRUCT_FOR_ID(nbytes) STRUCT_FOR_ID(ndigits) STRUCT_FOR_ID(nested) STRUCT_FOR_ID(new_file_name) @@ -684,6 +688,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(onceregistry) STRUCT_FOR_ID(only_active_thread) STRUCT_FOR_ID(only_keys) + STRUCT_FOR_ID(op) STRUCT_FOR_ID(oparg) STRUCT_FOR_ID(opcode) STRUCT_FOR_ID(opcodes) @@ -718,6 +723,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(pidfd) STRUCT_FOR_ID(pointer_bits) STRUCT_FOR_ID(policy) + STRUCT_FOR_ID(port) STRUCT_FOR_ID(pos) STRUCT_FOR_ID(pos1) STRUCT_FOR_ID(pos2) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 378f27ca17b5079..5a194478f562314 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -1594,6 +1594,7 @@ extern "C" { INIT_ID(argv), \ INIT_ID(as_integer_ratio), \ INIT_ID(asend), \ + INIT_ID(assoclen), \ INIT_ID(ast), \ INIT_ID(athrow), \ INIT_ID(attr), \ @@ -1809,6 +1810,7 @@ extern "C" { INIT_ID(headers), \ INIT_ID(hi), \ INIT_ID(hook), \ + INIT_ID(host), \ INIT_ID(hour), \ INIT_ID(hours), \ INIT_ID(id), \ @@ -1857,6 +1859,7 @@ extern "C" { INIT_ID(iter), \ INIT_ID(iterable), \ INIT_ID(iterations), \ + INIT_ID(iv), \ INIT_ID(join), \ INIT_ID(jump), \ INIT_ID(keepends), \ @@ -1935,6 +1938,7 @@ extern "C" { INIT_ID(namespace_separator), \ INIT_ID(namespaces), \ INIT_ID(native), \ + INIT_ID(nbytes), \ INIT_ID(ndigits), \ INIT_ID(nested), \ INIT_ID(new_file_name), \ @@ -1959,6 +1963,7 @@ extern "C" { INIT_ID(onceregistry), \ INIT_ID(only_active_thread), \ INIT_ID(only_keys), \ + INIT_ID(op), \ INIT_ID(oparg), \ INIT_ID(opcode), \ INIT_ID(opcodes), \ @@ -1993,6 +1998,7 @@ extern "C" { INIT_ID(pidfd), \ INIT_ID(pointer_bits), \ INIT_ID(policy), \ + INIT_ID(port), \ INIT_ID(pos), \ INIT_ID(pos1), \ INIT_ID(pos2), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index daf6840aa47f328..25529c5ca713a95 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -1056,6 +1056,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(assoclen); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(ast); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -1916,6 +1920,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(host); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(hour); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2108,6 +2116,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(iv); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(join); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2420,6 +2432,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(nbytes); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(ndigits); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2516,6 +2532,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(op); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(oparg); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2652,6 +2672,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(port); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(pos); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 5153e5eb9a4ff8b..83b1ef37185e859 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -6312,6 +6312,25 @@ def test_signal_module_has_signatures(self): import signal self._test_module_has_signatures(signal) + def test_socket_module_has_signatures(self): + import socket + # The socket type has no signature, it is created by socket(). + no_signature = {'SocketType'} + # The C default is NULL and None is not accepted + unsupported_signature = {'getservbyname', 'getservbyport'} + # Not all functions and methods are available on all platforms. + unsupported_signature &= vars(socket).keys() + # These cannot be converted to Argument Clinic: their behaviour + # depends on the number of the arguments. + methods_no_signature = {'ioctl', 'sendto', 'setsockopt'} + # These have parameters with unrepresentable default values. + methods_unsupported_signature = {'listen', 'sendmsg', 'sendmsg_afalg'} + defined = vars(socket.SocketType).keys() + self._test_module_has_signatures(socket, + no_signature, unsupported_signature, + {'SocketType': methods_no_signature & defined}, + {'SocketType': methods_unsupported_signature & defined}) + def test_stat_module_has_signatures(self): import stat self._test_module_has_signatures(stat) diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h index b565e7516d50f33..51dbce40374ec7a 100644 --- a/Modules/clinic/socketmodule.c.h +++ b/Modules/clinic/socketmodule.c.h @@ -6,29 +6,911 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_long.h" // _PyLong_UInt16_Converter() #include "pycore_modsupport.h" // _PyArg_CheckPositional() +#if (defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4)) + +PyDoc_STRVAR(_socket_socket__accept__doc__, +"_accept($self, /)\n" +"--\n" +"\n" +"Wait for an incoming connection.\n" +"\n" +"Return a new socket file descriptor representing the connection, and\n" +"the address of the client. For IP sockets, the address info is a\n" +"pair (hostaddr, port)."); + +#define _SOCKET_SOCKET__ACCEPT_METHODDEF \ + {"_accept", (PyCFunction)_socket_socket__accept, METH_NOARGS, _socket_socket__accept__doc__}, + +static PyObject * +_socket_socket__accept_impl(PySocketSockObject *s); + +static PyObject * +_socket_socket__accept(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket__accept_impl((PySocketSockObject *)s); +} + +#endif /* (defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4)) */ + +PyDoc_STRVAR(_socket_socket_setblocking__doc__, +"setblocking($self, flag, /)\n" +"--\n" +"\n" +"Set the socket to blocking (flag is true) or non-blocking (false).\n" +"\n" +"setblocking(True) is equivalent to settimeout(None);\n" +"setblocking(False) is equivalent to settimeout(0.0)."); + +#define _SOCKET_SOCKET_SETBLOCKING_METHODDEF \ + {"setblocking", (PyCFunction)_socket_socket_setblocking, METH_O, _socket_socket_setblocking__doc__}, + +static PyObject * +_socket_socket_setblocking_impl(PySocketSockObject *s, PyObject *arg); + +static PyObject * +_socket_socket_setblocking(PyObject *s, PyObject *arg) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_setblocking_impl((PySocketSockObject *)s, arg); + + return return_value; +} + +PyDoc_STRVAR(_socket_socket_getblocking__doc__, +"getblocking($self, /)\n" +"--\n" +"\n" +"Return True if socket is in blocking mode, False if in non-blocking."); + +#define _SOCKET_SOCKET_GETBLOCKING_METHODDEF \ + {"getblocking", (PyCFunction)_socket_socket_getblocking, METH_NOARGS, _socket_socket_getblocking__doc__}, + +static PyObject * +_socket_socket_getblocking_impl(PySocketSockObject *s); + +static PyObject * +_socket_socket_getblocking(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket_getblocking_impl((PySocketSockObject *)s); +} + +PyDoc_STRVAR(_socket_socket_settimeout__doc__, +"settimeout($self, timeout, /)\n" +"--\n" +"\n" +"Set a timeout on socket operations.\n" +"\n" +"\'timeout\' can be a float, giving in seconds, or None. Setting a\n" +"timeout of None disables the timeout feature and is equivalent to\n" +"setblocking(1). Setting a timeout of zero is the same as\n" +"setblocking(0)."); + +#define _SOCKET_SOCKET_SETTIMEOUT_METHODDEF \ + {"settimeout", (PyCFunction)_socket_socket_settimeout, METH_O, _socket_socket_settimeout__doc__}, + +static PyObject * +_socket_socket_settimeout_impl(PySocketSockObject *s, PyObject *arg); + +static PyObject * +_socket_socket_settimeout(PyObject *s, PyObject *arg) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_settimeout_impl((PySocketSockObject *)s, arg); + + return return_value; +} + +PyDoc_STRVAR(_socket_socket_gettimeout__doc__, +"gettimeout($self, /)\n" +"--\n" +"\n" +"Return the timeout in seconds (float) of socket operations.\n" +"\n" +"A timeout of None indicates that timeouts on socket operations are\n" +"disabled."); + +#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)) +{ + return _socket_socket_gettimeout_impl((PySocketSockObject *)self); +} + +PyDoc_STRVAR(_socket_socket_getsockopt__doc__, +"getsockopt($self, level, option, buffersize=0, /)\n" +"--\n" +"\n" +"Get a socket option.\n" +"\n" +"See the Unix manual for level and option. If a nonzero buffersize\n" +"argument is given, the return value is a bytes object of that\n" +"length; otherwise it is an integer."); + +#define _SOCKET_SOCKET_GETSOCKOPT_METHODDEF \ + {"getsockopt", _PyCFunction_CAST(_socket_socket_getsockopt), METH_FASTCALL, _socket_socket_getsockopt__doc__}, + +static PyObject * +_socket_socket_getsockopt_impl(PySocketSockObject *s, int level, int optname, + int buflen); + +static PyObject * +_socket_socket_getsockopt(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int level; + int optname; + int buflen = 0; + + if (!_PyArg_CheckPositional("getsockopt", nargs, 2, 3)) { + goto exit; + } + level = PyLong_AsInt(args[0]); + if (level == -1 && PyErr_Occurred()) { + goto exit; + } + optname = PyLong_AsInt(args[1]); + if (optname == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + buflen = PyLong_AsInt(args[2]); + if (buflen == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_getsockopt_impl((PySocketSockObject *)s, level, optname, buflen); + +exit: + return return_value; +} + +#if defined(HAVE_BIND) + +PyDoc_STRVAR(_socket_socket_bind__doc__, +"bind($self, address, /)\n" +"--\n" +"\n" +"Bind the socket to a local address.\n" +"\n" +"For IP sockets, the address is a pair (host, port); the host must\n" +"refer to the local host. For raw packet sockets the address is a\n" +"tuple (ifname, proto [,pkttype [,hatype [,addr]]])."); + +#define _SOCKET_SOCKET_BIND_METHODDEF \ + {"bind", (PyCFunction)_socket_socket_bind, METH_O, _socket_socket_bind__doc__}, + +static PyObject * +_socket_socket_bind_impl(PySocketSockObject *s, PyObject *addro); + +static PyObject * +_socket_socket_bind(PyObject *s, PyObject *addro) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_bind_impl((PySocketSockObject *)s, addro); + + return return_value; +} + +#endif /* defined(HAVE_BIND) */ + PyDoc_STRVAR(_socket_socket_close__doc__, "close($self, /)\n" "--\n" "\n" -"close()\n" +"close()\n" +"\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 *s); + +static PyObject * +_socket_socket_close(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket_close_impl((PySocketSockObject *)s); +} + +PyDoc_STRVAR(_socket_socket_detach__doc__, +"detach($self, /)\n" +"--\n" +"\n" +"Close the socket object without closing the file descriptor.\n" +"\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."); + +#define _SOCKET_SOCKET_DETACH_METHODDEF \ + {"detach", (PyCFunction)_socket_socket_detach, METH_NOARGS, _socket_socket_detach__doc__}, + +static PyObject * +_socket_socket_detach_impl(PySocketSockObject *s); + +static PyObject * +_socket_socket_detach(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket_detach_impl((PySocketSockObject *)s); +} + +#if defined(HAVE_CONNECT) + +PyDoc_STRVAR(_socket_socket_connect__doc__, +"connect($self, address, /)\n" +"--\n" +"\n" +"Connect the socket to a remote address.\n" +"\n" +"For IP sockets, the address is a pair (host, port)."); + +#define _SOCKET_SOCKET_CONNECT_METHODDEF \ + {"connect", (PyCFunction)_socket_socket_connect, METH_O, _socket_socket_connect__doc__}, + +static PyObject * +_socket_socket_connect_impl(PySocketSockObject *s, PyObject *addro); + +static PyObject * +_socket_socket_connect(PyObject *s, PyObject *addro) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_connect_impl((PySocketSockObject *)s, addro); + + return return_value; +} + +#endif /* defined(HAVE_CONNECT) */ + +#if defined(HAVE_CONNECT) + +PyDoc_STRVAR(_socket_socket_connect_ex__doc__, +"connect_ex($self, address, /)\n" +"--\n" +"\n" +"Connect the socket to a remote address.\n" +"\n" +"This is like connect(address), but returns an error code (the errno\n" +"value) instead of raising an exception when an error occurs."); + +#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_impl(PySocketSockObject *s, PyObject *addro); + +static PyObject * +_socket_socket_connect_ex(PyObject *s, PyObject *addro) +{ + PyObject *return_value = NULL; + + return_value = _socket_socket_connect_ex_impl((PySocketSockObject *)s, addro); + + return return_value; +} + +#endif /* defined(HAVE_CONNECT) */ + +PyDoc_STRVAR(_socket_socket_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\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 *s); + +static PyObject * +_socket_socket_fileno(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket_fileno_impl((PySocketSockObject *)s); +} + +#if defined(HAVE_GETSOCKNAME) + +PyDoc_STRVAR(_socket_socket_getsockname__doc__, +"getsockname($self, /)\n" +"--\n" +"\n" +"Return the address of the local endpoint.\n" +"\n" +"The format depends on the address family. For IPv4 sockets, the\n" +"address info is a pair (hostaddr, port). For IPv6 sockets, the\n" +"address info is a 4-tuple (hostaddr, port, flowinfo, scope_id)."); + +#define _SOCKET_SOCKET_GETSOCKNAME_METHODDEF \ + {"getsockname", (PyCFunction)_socket_socket_getsockname, METH_NOARGS, _socket_socket_getsockname__doc__}, + +static PyObject * +_socket_socket_getsockname_impl(PySocketSockObject *s); + +static PyObject * +_socket_socket_getsockname(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket_getsockname_impl((PySocketSockObject *)s); +} + +#endif /* defined(HAVE_GETSOCKNAME) */ + +#if defined(HAVE_GETPEERNAME) + +PyDoc_STRVAR(_socket_socket_getpeername__doc__, +"getpeername($self, /)\n" +"--\n" +"\n" +"Return the address of the remote endpoint.\n" +"\n" +"For IP sockets, the address info 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 *s); + +static PyObject * +_socket_socket_getpeername(PyObject *s, PyObject *Py_UNUSED(ignored)) +{ + return _socket_socket_getpeername_impl((PySocketSockObject *)s); +} + +#endif /* defined(HAVE_GETPEERNAME) */ + +#if defined(HAVE_LISTEN) + +PyDoc_STRVAR(_socket_socket_listen__doc__, +"listen($self, backlog=min(SOMAXCONN, 128), /)\n" +"--\n" +"\n" +"Enable a server to accept connections.\n" +"\n" +"If backlog is specified, it must be at least 0 (if it is lower, it\n" +"is set to 0); it specifies the number of unaccepted connections that\n" +"the system will allow before refusing new connections. If not\n" +"specified, a default reasonable value is chosen."); + +#define _SOCKET_SOCKET_LISTEN_METHODDEF \ + {"listen", _PyCFunction_CAST(_socket_socket_listen), METH_FASTCALL, _socket_socket_listen__doc__}, + +static PyObject * +_socket_socket_listen_impl(PySocketSockObject *s, int backlog); + +static PyObject * +_socket_socket_listen(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int backlog = Py_MIN(SOMAXCONN, 128); + + if (!_PyArg_CheckPositional("listen", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + backlog = PyLong_AsInt(args[0]); + if (backlog == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_listen_impl((PySocketSockObject *)s, backlog); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LISTEN) */ + +PyDoc_STRVAR(_socket_socket_recv__doc__, +"recv($self, buffersize, flags=0, /)\n" +"--\n" +"\n" +"Receive up to buffersize bytes from the socket.\n" +"\n" +"For the optional flags argument, see the Unix manual. When no data\n" +"is available, block until at least one byte is available or until\n" +"the remote end is closed. When the remote end is closed and all data\n" +"is read, return the empty string."); + +#define _SOCKET_SOCKET_RECV_METHODDEF \ + {"recv", _PyCFunction_CAST(_socket_socket_recv), METH_FASTCALL, _socket_socket_recv__doc__}, + +static PyObject * +_socket_socket_recv_impl(PySocketSockObject *s, Py_ssize_t recvlen, + int flags); + +static PyObject * +_socket_socket_recv(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t recvlen; + int flags = 0; + + if (!_PyArg_CheckPositional("recv", nargs, 1, 2)) { + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + recvlen = ival; + } + if (nargs < 2) { + goto skip_optional; + } + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_recv_impl((PySocketSockObject *)s, recvlen, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_socket_socket_recv_into__doc__, +"recv_into($self, /, buffer, nbytes=0, flags=0)\n" +"--\n" +"\n" +"Receive up to nbytes bytes from the socket, storing into a buffer.\n" +"\n" +"A version of recv() that stores its data into a buffer rather than\n" +"creating a new bytes object. If nbytes is not specified (or 0),\n" +"receive up to the size available in the given buffer.\n" +"\n" +"See recv() for documentation about the flags."); + +#define _SOCKET_SOCKET_RECV_INTO_METHODDEF \ + {"recv_into", _PyCFunction_CAST(_socket_socket_recv_into), METH_FASTCALL|METH_KEYWORDS, _socket_socket_recv_into__doc__}, + +static PyObject * +_socket_socket_recv_into_impl(PySocketSockObject *s, Py_buffer *pbuf, + Py_ssize_t recvlen, int flags); + +static PyObject * +_socket_socket_recv_into(PyObject *s, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(buffer), &_Py_ID(nbytes), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"buffer", "nbytes", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "recv_into", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer pbuf = {NULL, NULL}; + Py_ssize_t recvlen = 0; + int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &pbuf, PyBUF_WRITABLE) < 0) { + _PyArg_BadArgument("recv_into", "argument 'buffer'", "read-write bytes-like object", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + recvlen = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + flags = PyLong_AsInt(args[2]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _socket_socket_recv_into_impl((PySocketSockObject *)s, &pbuf, recvlen, flags); + +exit: + /* Cleanup for pbuf */ + if (pbuf.obj) { + PyBuffer_Release(&pbuf); + } + + return return_value; +} + +#if defined(HAVE_RECVFROM) + +PyDoc_STRVAR(_socket_socket_recvfrom__doc__, +"recvfrom($self, buffersize, flags=0, /)\n" +"--\n" +"\n" +"Receive up to buffersize bytes and the sender\'s address info.\n" +"\n" +"Like recv(buffersize, flags), but return a (data, address info)\n" +"pair."); + +#define _SOCKET_SOCKET_RECVFROM_METHODDEF \ + {"recvfrom", _PyCFunction_CAST(_socket_socket_recvfrom), METH_FASTCALL, _socket_socket_recvfrom__doc__}, + +static PyObject * +_socket_socket_recvfrom_impl(PySocketSockObject *s, Py_ssize_t recvlen, + int flags); + +static PyObject * +_socket_socket_recvfrom(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t recvlen; + int flags = 0; + + if (!_PyArg_CheckPositional("recvfrom", nargs, 1, 2)) { + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + recvlen = ival; + } + if (nargs < 2) { + goto skip_optional; + } + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_recvfrom_impl((PySocketSockObject *)s, recvlen, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_RECVFROM) */ + +#if defined(HAVE_RECVFROM) + +PyDoc_STRVAR(_socket_socket_recvfrom_into__doc__, +"recvfrom_into($self, /, buffer, nbytes=0, flags=0)\n" +"--\n" +"\n" +"Receive up to nbytes bytes and the sender\'s address info.\n" +"\n" +"Like recv_into(buffer, nbytes, flags), but return a (nbytes, address\n" +"info) pair."); + +#define _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF \ + {"recvfrom_into", _PyCFunction_CAST(_socket_socket_recvfrom_into), METH_FASTCALL|METH_KEYWORDS, _socket_socket_recvfrom_into__doc__}, + +static PyObject * +_socket_socket_recvfrom_into_impl(PySocketSockObject *s, Py_buffer *pbuf, + Py_ssize_t recvlen, int flags); + +static PyObject * +_socket_socket_recvfrom_into(PyObject *s, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(buffer), &_Py_ID(nbytes), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"buffer", "nbytes", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "recvfrom_into", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer pbuf = {NULL, NULL}; + Py_ssize_t recvlen = 0; + int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &pbuf, PyBUF_WRITABLE) < 0) { + _PyArg_BadArgument("recvfrom_into", "argument 'buffer'", "read-write bytes-like object", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + recvlen = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + flags = PyLong_AsInt(args[2]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _socket_socket_recvfrom_into_impl((PySocketSockObject *)s, &pbuf, recvlen, flags); + +exit: + /* Cleanup for pbuf */ + if (pbuf.obj) { + PyBuffer_Release(&pbuf); + } + + return return_value; +} + +#endif /* defined(HAVE_RECVFROM) */ + +#if defined(CMSG_LEN) + +PyDoc_STRVAR(_socket_socket_recvmsg__doc__, +"recvmsg($self, bufsize, ancbufsize=0, flags=0, /)\n" +"--\n" +"\n" +"Receive normal data and ancillary data from the socket.\n" "\n" -"Close the socket. It cannot be used after this call."); +"Receive up to bufsize bytes of normal data. The ancbufsize argument\n" +"sets the size in bytes of the internal buffer used to receive the\n" +"ancillary data; it defaults to 0, meaning that no ancillary data\n" +"will be received. Appropriate buffer sizes for ancillary data can\n" +"be calculated using CMSG_SPACE() or CMSG_LEN(), and items which do\n" +"not fit into the buffer might be truncated or discarded. The flags\n" +"argument defaults to 0 and has the 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\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;\n" +"otherwise, its value is 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."); -#define _SOCKET_SOCKET_CLOSE_METHODDEF \ - {"close", (PyCFunction)_socket_socket_close, METH_NOARGS, _socket_socket_close__doc__}, +#define _SOCKET_SOCKET_RECVMSG_METHODDEF \ + {"recvmsg", _PyCFunction_CAST(_socket_socket_recvmsg), METH_FASTCALL, _socket_socket_recvmsg__doc__}, static PyObject * -_socket_socket_close_impl(PySocketSockObject *s); +_socket_socket_recvmsg_impl(PySocketSockObject *s, Py_ssize_t bufsize, + Py_ssize_t ancbufsize, int flags); static PyObject * -_socket_socket_close(PyObject *s, PyObject *Py_UNUSED(ignored)) +_socket_socket_recvmsg(PyObject *s, PyObject *const *args, Py_ssize_t nargs) { - return _socket_socket_close_impl((PySocketSockObject *)s); + PyObject *return_value = NULL; + Py_ssize_t bufsize; + Py_ssize_t ancbufsize = 0; + int flags = 0; + + if (!_PyArg_CheckPositional("recvmsg", nargs, 1, 3)) { + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + bufsize = ival; + } + if (nargs < 2) { + goto skip_optional; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + ancbufsize = ival; + } + if (nargs < 3) { + goto skip_optional; + } + flags = PyLong_AsInt(args[2]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_recvmsg_impl((PySocketSockObject *)s, bufsize, ancbufsize, flags); + +exit: + return return_value; +} + +#endif /* defined(CMSG_LEN) */ + +#if defined(CMSG_LEN) + +PyDoc_STRVAR(_socket_socket_recvmsg_into__doc__, +"recvmsg_into($self, buffers, ancbufsize=0, flags=0, /)\n" +"--\n" +"\n" +"Receive normal and ancillary data, scattering the normal data.\n" +"\n" +"The buffers argument must be an iterable of objects that export\n" +"writable buffers (e.g. bytearray objects); these will be filled\n" +"with successive chunks of the non-ancillary data until it has all\n" +"been written or there are no more buffers. The ancbufsize argument\n" +"sets the size in bytes of the internal buffer used to receive the\n" +"ancillary data; it defaults to 0, meaning that no ancillary data\n" +"will be received. Appropriate buffer sizes for ancillary data can\n" +"be calculated using CMSG_SPACE() or CMSG_LEN(), and items which do\n" +"not fit into the buffer might be truncated or discarded. The flags\n" +"argument defaults to 0 and has the same meaning as for recv().\n" +"\n" +"The return value is a 4-tuple: (nbytes, ancdata, msg_flags,\n" +"address). The nbytes item is the total number of bytes of\n" +"non-ancillary data written into the buffers. The ancdata item is a\n" +"list of zero or more tuples (cmsg_level, cmsg_type, cmsg_data)\n" +"representing the ancillary data (control messages) received:\n" +"cmsg_level and cmsg_type are integers specifying the protocol level\n" +"and protocol-specific type respectively, and cmsg_data is a bytes\n" +"object holding the associated data. The msg_flags item is the\n" +"bitwise OR of various flags indicating conditions on the received\n" +"message; see your system documentation for details. If the\n" +"receiving socket is unconnected, address is the address of the\n" +"sending socket, if available; otherwise, 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."); + +#define _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF \ + {"recvmsg_into", _PyCFunction_CAST(_socket_socket_recvmsg_into), METH_FASTCALL, _socket_socket_recvmsg_into__doc__}, + +static PyObject * +_socket_socket_recvmsg_into_impl(PySocketSockObject *s, + PyObject *buffers_arg, + Py_ssize_t ancbufsize, int flags); + +static PyObject * +_socket_socket_recvmsg_into(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *buffers_arg; + Py_ssize_t ancbufsize = 0; + int flags = 0; + + if (!_PyArg_CheckPositional("recvmsg_into", nargs, 1, 3)) { + goto exit; + } + buffers_arg = args[0]; + if (nargs < 2) { + goto skip_optional; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + ancbufsize = ival; + } + if (nargs < 3) { + goto skip_optional; + } + flags = PyLong_AsInt(args[2]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_recvmsg_into_impl((PySocketSockObject *)s, buffers_arg, ancbufsize, flags); + +exit: + return return_value; } +#endif /* defined(CMSG_LEN) */ + PyDoc_STRVAR(_socket_socket_send__doc__, "send($self, data, flags=0, /)\n" "--\n" @@ -111,89 +993,290 @@ _socket_socket_sendall(PyObject *s, PyObject *const *args, Py_ssize_t nargs) if (nargs < 2) { goto skip_optional; } - flags = PyLong_AsInt(args[1]); + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socket_sendall_impl((PySocketSockObject *)s, &pbuf, flags); + +exit: + /* Cleanup for pbuf */ + if (pbuf.obj) { + PyBuffer_Release(&pbuf); + } + + return return_value; +} + +#if defined(CMSG_LEN) + +PyDoc_STRVAR(_socket_socket_sendmsg__doc__, +"sendmsg($self, buffers, ancdata=, flags=0,\n" +" address=, /)\n" +"--\n" +"\n" +"Send normal and ancillary data to the socket.\n" +"\n" +"It gathering the non-ancillary data from a series of buffers\n" +"and concatenating it into a single message.\n" +"The buffers argument specifies the non-ancillary\n" +"data as an iterable of bytes-like 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\n" +"the protocol level and protocol-specific type respectively, and\n" +"cmsg_data is a bytes-like object holding the associated data. The\n" +"flags argument defaults to 0 and has the same meaning as for send().\n" +"If address is supplied and not None, it sets a destination address\n" +"for the message. The return value is the number of bytes of\n" +"non-ancillary data sent."); + +#define _SOCKET_SOCKET_SENDMSG_METHODDEF \ + {"sendmsg", _PyCFunction_CAST(_socket_socket_sendmsg), METH_FASTCALL, _socket_socket_sendmsg__doc__}, + +static PyObject * +_socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, + PyObject *cmsg_arg, int flags, + PyObject *addr_arg); + +static PyObject * +_socket_socket_sendmsg(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *data_arg; + PyObject *cmsg_arg = NULL; + int flags = 0; + PyObject *addr_arg = NULL; + + if (!_PyArg_CheckPositional("sendmsg", nargs, 1, 4)) { + goto exit; + } + data_arg = args[0]; + if (nargs < 2) { + goto skip_optional; + } + cmsg_arg = args[1]; + if (nargs < 3) { + goto skip_optional; + } + flags = PyLong_AsInt(args[2]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + addr_arg = args[3]; +skip_optional: + return_value = _socket_socket_sendmsg_impl((PySocketSockObject *)s, data_arg, cmsg_arg, flags, addr_arg); + +exit: + return return_value; +} + +#endif /* defined(CMSG_LEN) */ + +#if defined(HAVE_SOCKADDR_ALG) + +PyDoc_STRVAR(_socket_socket_sendmsg_afalg__doc__, +"sendmsg_afalg($self, /, msg=, *, op=,\n" +" iv=, assoclen=, flags=0)\n" +"--\n" +"\n" +"Set operation mode, IV and associated data length.\n" +"\n" +"For an AF_ALG operation socket."); + +#define _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF \ + {"sendmsg_afalg", _PyCFunction_CAST(_socket_socket_sendmsg_afalg), METH_FASTCALL|METH_KEYWORDS, _socket_socket_sendmsg_afalg__doc__}, + +static PyObject * +_socket_socket_sendmsg_afalg_impl(PySocketSockObject *self, + PyObject *data_arg, PyObject *opobj, + Py_buffer *iv, PyObject *assoclenobj, + int flags); + +static PyObject * +_socket_socket_sendmsg_afalg(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(msg), &_Py_ID(op), &_Py_ID(iv), &_Py_ID(assoclen), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"msg", "op", "iv", "assoclen", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendmsg_afalg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_arg = NULL; + PyObject *opobj = NULL; + Py_buffer iv = {NULL, NULL}; + PyObject *assoclenobj = NULL; + int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + data_arg = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + if (!PyLong_Check(args[1])) { + _PyArg_BadArgument("sendmsg_afalg", "argument 'op'", "int", args[1]); + goto exit; + } + opobj = args[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (PyObject_GetBuffer(args[2], &iv, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!PyLong_Check(args[3])) { + _PyArg_BadArgument("sendmsg_afalg", "argument 'assoclen'", "int", args[3]); + goto exit; + } + assoclenobj = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + flags = PyLong_AsInt(args[4]); if (flags == -1 && PyErr_Occurred()) { goto exit; } -skip_optional: - return_value = _socket_socket_sendall_impl((PySocketSockObject *)s, &pbuf, flags); +skip_optional_kwonly: + return_value = _socket_socket_sendmsg_afalg_impl((PySocketSockObject *)self, data_arg, opobj, &iv, assoclenobj, flags); exit: - /* Cleanup for pbuf */ - if (pbuf.obj) { - PyBuffer_Release(&pbuf); + /* Cleanup for iv */ + if (iv.obj) { + PyBuffer_Release(&iv); } return return_value; } -#if defined(CMSG_LEN) +#endif /* defined(HAVE_SOCKADDR_ALG) */ -PyDoc_STRVAR(_socket_socket_sendmsg__doc__, -"sendmsg($self, buffers, ancdata=, flags=0,\n" -" address=, /)\n" +#if defined(HAVE_SHUTDOWN) + +PyDoc_STRVAR(_socket_socket_shutdown__doc__, +"shutdown($self, flag, /)\n" "--\n" "\n" -"Send normal and ancillary data to the socket.\n" +"Shut down one or both halves of the connection.\n" "\n" -"It gathering the non-ancillary data from a series of buffers\n" -"and concatenating it into a single message.\n" -"The buffers argument specifies the non-ancillary\n" -"data as an iterable of bytes-like 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\n" -"the protocol level and protocol-specific type respectively, and\n" -"cmsg_data is a bytes-like object holding the associated data. The\n" -"flags argument defaults to 0 and has the same meaning as for send().\n" -"If address is supplied and not None, it sets a destination address\n" -"for the message. The return value is the number of bytes of\n" -"non-ancillary data sent."); +"Shut down the reading side of the socket (flag == SHUT_RD), the\n" +"writing side of the socket (flag == SHUT_WR), or both ends (flag ==\n" +"SHUT_RDWR)."); -#define _SOCKET_SOCKET_SENDMSG_METHODDEF \ - {"sendmsg", _PyCFunction_CAST(_socket_socket_sendmsg), METH_FASTCALL, _socket_socket_sendmsg__doc__}, +#define _SOCKET_SOCKET_SHUTDOWN_METHODDEF \ + {"shutdown", (PyCFunction)_socket_socket_shutdown, METH_O, _socket_socket_shutdown__doc__}, static PyObject * -_socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, - PyObject *cmsg_arg, int flags, - PyObject *addr_arg); +_socket_socket_shutdown_impl(PySocketSockObject *s, PyObject *arg); static PyObject * -_socket_socket_sendmsg(PyObject *s, PyObject *const *args, Py_ssize_t nargs) +_socket_socket_shutdown(PyObject *s, PyObject *arg) { PyObject *return_value = NULL; - PyObject *data_arg; - PyObject *cmsg_arg = NULL; - int flags = 0; - PyObject *addr_arg = NULL; - if (!_PyArg_CheckPositional("sendmsg", nargs, 1, 4)) { - goto exit; - } - data_arg = args[0]; - if (nargs < 2) { - goto skip_optional; - } - cmsg_arg = args[1]; - if (nargs < 3) { - goto skip_optional; - } - flags = PyLong_AsInt(args[2]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } - if (nargs < 4) { - goto skip_optional; + return_value = _socket_socket_shutdown_impl((PySocketSockObject *)s, arg); + + return return_value; +} + +#endif /* defined(HAVE_SHUTDOWN) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_socket_socket_share__doc__, +"share($self, process_id, /)\n" +"--\n" +"\n" +"Share the socket with another process.\n" +"\n" +"The target process id must be provided and the resulting bytes\n" +"object passed to the target process. There the shared socket can be\n" +"instantiated by calling socket.fromshare()."); + +#define _SOCKET_SOCKET_SHARE_METHODDEF \ + {"share", (PyCFunction)_socket_socket_share, METH_O, _socket_socket_share__doc__}, + +static PyObject * +_socket_socket_share_impl(PySocketSockObject *s, unsigned int processId); + +static PyObject * +_socket_socket_share(PyObject *s, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned int processId; + + { + Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &processId, sizeof(unsigned int), + Py_ASNATIVEBYTES_NATIVE_ENDIAN | + Py_ASNATIVEBYTES_ALLOW_INDEX | + Py_ASNATIVEBYTES_UNSIGNED_BUFFER); + if (_bytes < 0) { + goto exit; + } + if ((size_t)_bytes > sizeof(unsigned int)) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "integer value out of range", 1) < 0) + { + goto exit; + } + } } - addr_arg = args[3]; -skip_optional: - return_value = _socket_socket_sendmsg_impl((PySocketSockObject *)s, data_arg, cmsg_arg, flags, addr_arg); + return_value = _socket_socket_share_impl((PySocketSockObject *)s, processId); exit: return return_value; } -#endif /* defined(CMSG_LEN) */ +#endif /* defined(MS_WINDOWS) */ static int sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, @@ -282,6 +1365,334 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) return return_value; } +#if defined(HAVE_GETHOSTNAME) + +PyDoc_STRVAR(_socket_gethostname__doc__, +"gethostname($module, /)\n" +"--\n" +"\n" +"Return the current host name."); + +#define _SOCKET_GETHOSTNAME_METHODDEF \ + {"gethostname", (PyCFunction)_socket_gethostname, METH_NOARGS, _socket_gethostname__doc__}, + +static PyObject * +_socket_gethostname_impl(PyObject *module); + +static PyObject * +_socket_gethostname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _socket_gethostname_impl(module); +} + +#endif /* defined(HAVE_GETHOSTNAME) */ + +#if defined(HAVE_SETHOSTNAME) + +PyDoc_STRVAR(_socket_sethostname__doc__, +"sethostname($module, name, /)\n" +"--\n" +"\n" +"Set the hostname to name."); + +#define _SOCKET_SETHOSTNAME_METHODDEF \ + {"sethostname", (PyCFunction)_socket_sethostname, METH_O, _socket_sethostname__doc__}, + +#endif /* defined(HAVE_SETHOSTNAME) */ + +#if defined(HAVE_GETADDRINFO) + +PyDoc_STRVAR(_socket_gethostbyname__doc__, +"gethostbyname($module, host, /)\n" +"--\n" +"\n" +"Return the IP address for a host.\n" +"\n" +"The address is a string of the form \'255.255.255.255\'."); + +#define _SOCKET_GETHOSTBYNAME_METHODDEF \ + {"gethostbyname", (PyCFunction)_socket_gethostbyname, METH_O, _socket_gethostbyname__doc__}, + +#endif /* defined(HAVE_GETADDRINFO) */ + +#if (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME)) + +PyDoc_STRVAR(_socket_gethostbyname_ex__doc__, +"gethostbyname_ex($module, host, /)\n" +"--\n" +"\n" +"Map a host name to its IP number.\n" +"\n" +"Return the true host name, a list of aliases, and a list of IP\n" +"addresses, which are strings of the form \'255.255.255.255\'."); + +#define _SOCKET_GETHOSTBYNAME_EX_METHODDEF \ + {"gethostbyname_ex", (PyCFunction)_socket_gethostbyname_ex, METH_O, _socket_gethostbyname_ex__doc__}, + +#endif /* (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME)) */ + +#if (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR)) + +PyDoc_STRVAR(_socket_gethostbyaddr__doc__, +"gethostbyaddr($module, host, /)\n" +"--\n" +"\n" +"Map an IP number or host name to the true host name and addresses.\n" +"\n" +"Return the true host name, a list of aliases, and a list of IP\n" +"addresses. The host argument is a string giving a host name or IP\n" +"number."); + +#define _SOCKET_GETHOSTBYADDR_METHODDEF \ + {"gethostbyaddr", (PyCFunction)_socket_gethostbyaddr, METH_O, _socket_gethostbyaddr__doc__}, + +#endif /* (defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR)) */ + +#if defined(HAVE_GETSERVBYNAME) + +PyDoc_STRVAR(_socket_getservbyname__doc__, +"getservbyname($module, servicename, protocolname=, /)\n" +"--\n" +"\n" +"Return a port number from a service name and protocol name.\n" +"\n" +"The optional protocol name, if given, should be \'tcp\' or \'udp\',\n" +"otherwise any protocol will match."); + +#define _SOCKET_GETSERVBYNAME_METHODDEF \ + {"getservbyname", _PyCFunction_CAST(_socket_getservbyname), METH_FASTCALL, _socket_getservbyname__doc__}, + +static PyObject * +_socket_getservbyname_impl(PyObject *module, const char *name, + const char *proto); + +static PyObject * +_socket_getservbyname(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *name; + const char *proto = NULL; + + if (!_PyArg_CheckPositional("getservbyname", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("getservbyname", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("getservbyname", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t proto_length; + proto = PyUnicode_AsUTF8AndSize(args[1], &proto_length); + if (proto == NULL) { + goto exit; + } + if (strlen(proto) != (size_t)proto_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional: + return_value = _socket_getservbyname_impl(module, name, proto); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETSERVBYNAME) */ + +#if defined(HAVE_GETSERVBYPORT) + +PyDoc_STRVAR(_socket_getservbyport__doc__, +"getservbyport($module, port, protocolname=, /)\n" +"--\n" +"\n" +"Return the service name from a port number and protocol name.\n" +"\n" +"The optional protocol name, if given, should be \'tcp\' or \'udp\',\n" +"otherwise any protocol will match."); + +#define _SOCKET_GETSERVBYPORT_METHODDEF \ + {"getservbyport", _PyCFunction_CAST(_socket_getservbyport), METH_FASTCALL, _socket_getservbyport__doc__}, + +static PyObject * +_socket_getservbyport_impl(PyObject *module, int port, const char *proto); + +static PyObject * +_socket_getservbyport(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int port; + const char *proto = NULL; + + if (!_PyArg_CheckPositional("getservbyport", nargs, 1, 2)) { + goto exit; + } + port = PyLong_AsInt(args[0]); + if (port == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("getservbyport", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t proto_length; + proto = PyUnicode_AsUTF8AndSize(args[1], &proto_length); + if (proto == NULL) { + goto exit; + } + if (strlen(proto) != (size_t)proto_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional: + return_value = _socket_getservbyport_impl(module, port, proto); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETSERVBYPORT) */ + +#if defined(HAVE_GETPROTOBYNAME) + +PyDoc_STRVAR(_socket_getprotobyname__doc__, +"getprotobyname($module, name, /)\n" +"--\n" +"\n" +"Return the protocol number for the named protocol."); + +#define _SOCKET_GETPROTOBYNAME_METHODDEF \ + {"getprotobyname", (PyCFunction)_socket_getprotobyname, METH_O, _socket_getprotobyname__doc__}, + +static PyObject * +_socket_getprotobyname_impl(PyObject *module, const char *name); + +static PyObject * +_socket_getprotobyname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("getprotobyname", "argument", "str", arg); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _socket_getprotobyname_impl(module, name); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETPROTOBYNAME) */ + +PyDoc_STRVAR(_socket_close__doc__, +"close($module, fd, /)\n" +"--\n" +"\n" +"Close a socket fd."); + +#define _SOCKET_CLOSE_METHODDEF \ + {"close", (PyCFunction)_socket_close, METH_O, _socket_close__doc__}, + +#if !defined(NO_DUP) + +PyDoc_STRVAR(_socket_dup__doc__, +"dup($module, fd, /)\n" +"--\n" +"\n" +"Duplicate a socket descriptor.\n" +"\n" +"The new descriptor is non-inheritable."); + +#define _SOCKET_DUP_METHODDEF \ + {"dup", (PyCFunction)_socket_dup, METH_O, _socket_dup__doc__}, + +#endif /* !defined(NO_DUP) */ + +#if defined(HAVE_SOCKETPAIR) + +PyDoc_STRVAR(_socket_socketpair__doc__, +"socketpair($module, family=AF_UNIX, type=SOCK_STREAM, proto=0, /)\n" +"--\n" +"\n" +"Create a pair of connected socket objects.\n" +"\n" +"The sockets are returned by the platform socketpair() function. The\n" +"arguments are the same as for socket()."); + +#define _SOCKET_SOCKETPAIR_METHODDEF \ + {"socketpair", _PyCFunction_CAST(_socket_socketpair), METH_FASTCALL, _socket_socketpair__doc__}, + +static PyObject * +_socket_socketpair_impl(PyObject *module, int family, int type, int proto); + +static PyObject * +_socket_socketpair(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int family = AF_UNIX; + int type = SOCK_STREAM; + int proto = 0; + + if (!_PyArg_CheckPositional("socketpair", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + family = PyLong_AsInt(args[0]); + if (family == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + type = PyLong_AsInt(args[1]); + if (type == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + proto = PyLong_AsInt(args[2]); + if (proto == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _socket_socketpair_impl(module, family, type, proto); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SOCKETPAIR) */ + PyDoc_STRVAR(_socket_ntohs__doc__, "ntohs($module, integer, /)\n" "--\n" @@ -463,6 +1874,301 @@ _socket_inet_ntoa(PyObject *module, PyObject *arg) #endif /* defined(HAVE_INET_NTOA) */ +#if defined(HAVE_INET_PTON) + +PyDoc_STRVAR(_socket_inet_pton__doc__, +"inet_pton($module, af, ip, /)\n" +"--\n" +"\n" +"Convert an IP address from string format to a packed string.\n" +"\n" +"The string is suitable for use with low-level network functions."); + +#define _SOCKET_INET_PTON_METHODDEF \ + {"inet_pton", _PyCFunction_CAST(_socket_inet_pton), METH_FASTCALL, _socket_inet_pton__doc__}, + +static PyObject * +_socket_inet_pton_impl(PyObject *module, int af, const char *ip); + +static PyObject * +_socket_inet_pton(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int af; + const char *ip; + + if (!_PyArg_CheckPositional("inet_pton", nargs, 2, 2)) { + goto exit; + } + af = PyLong_AsInt(args[0]); + if (af == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("inet_pton", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t ip_length; + ip = PyUnicode_AsUTF8AndSize(args[1], &ip_length); + if (ip == NULL) { + goto exit; + } + if (strlen(ip) != (size_t)ip_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _socket_inet_pton_impl(module, af, ip); + +exit: + return return_value; +} + +#endif /* defined(HAVE_INET_PTON) */ + +#if defined(HAVE_INET_PTON) + +PyDoc_STRVAR(_socket_inet_ntop__doc__, +"inet_ntop($module, af, packed_ip, /)\n" +"--\n" +"\n" +"Convert a packed IP address of the given family to string format."); + +#define _SOCKET_INET_NTOP_METHODDEF \ + {"inet_ntop", _PyCFunction_CAST(_socket_inet_ntop), METH_FASTCALL, _socket_inet_ntop__doc__}, + +static PyObject * +_socket_inet_ntop_impl(PyObject *module, int af, Py_buffer *packed_ip); + +static PyObject * +_socket_inet_ntop(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int af; + Py_buffer packed_ip = {NULL, NULL}; + + if (!_PyArg_CheckPositional("inet_ntop", nargs, 2, 2)) { + goto exit; + } + af = PyLong_AsInt(args[0]); + if (af == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &packed_ip, PyBUF_SIMPLE) != 0) { + goto exit; + } + return_value = _socket_inet_ntop_impl(module, af, &packed_ip); + +exit: + /* Cleanup for packed_ip */ + if (packed_ip.obj) { + PyBuffer_Release(&packed_ip); + } + + return return_value; +} + +#endif /* defined(HAVE_INET_PTON) */ + +#if defined(HAVE_GETADDRINFO) + +PyDoc_STRVAR(_socket_getaddrinfo__doc__, +"getaddrinfo($module, /, host, port, family=AF_UNSPEC, type=0, proto=0,\n" +" flags=0)\n" +"--\n" +"\n" +"Resolve host and port into a list of 5-tuples.\n" +"\n" +"Each tuple is (family, type, proto, canonname, sockaddr)."); + +#define _SOCKET_GETADDRINFO_METHODDEF \ + {"getaddrinfo", _PyCFunction_CAST(_socket_getaddrinfo), METH_FASTCALL|METH_KEYWORDS, _socket_getaddrinfo__doc__}, + +static PyObject * +_socket_getaddrinfo_impl(PyObject *module, PyObject *hobj, PyObject *pobj, + int family, int socktype, int protocol, int flags); + +static PyObject * +_socket_getaddrinfo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(host), &_Py_ID(port), &_Py_ID(family), &_Py_ID(type), &_Py_ID(proto), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"host", "port", "family", "type", "proto", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getaddrinfo", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[6]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *hobj; + PyObject *pobj; + int family = AF_UNSPEC; + int socktype = 0; + int protocol = 0; + int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 2, /*maxpos*/ 6, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + hobj = args[0]; + pobj = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + family = PyLong_AsInt(args[2]); + if (family == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + socktype = PyLong_AsInt(args[3]); + if (socktype == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[4]) { + protocol = PyLong_AsInt(args[4]); + if (protocol == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + flags = PyLong_AsInt(args[5]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _socket_getaddrinfo_impl(module, hobj, pobj, family, socktype, protocol, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETADDRINFO) */ + +#if defined(HAVE_GETNAMEINFO) + +PyDoc_STRVAR(_socket_getnameinfo__doc__, +"getnameinfo($module, sockaddr, flags, /)\n" +"--\n" +"\n" +"Get host and port for a sockaddr."); + +#define _SOCKET_GETNAMEINFO_METHODDEF \ + {"getnameinfo", _PyCFunction_CAST(_socket_getnameinfo), METH_FASTCALL, _socket_getnameinfo__doc__}, + +static PyObject * +_socket_getnameinfo_impl(PyObject *module, PyObject *sa, int flags); + +static PyObject * +_socket_getnameinfo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sa; + int flags; + + if (!_PyArg_CheckPositional("getnameinfo", nargs, 2, 2)) { + goto exit; + } + sa = args[0]; + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _socket_getnameinfo_impl(module, sa, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETNAMEINFO) */ + +PyDoc_STRVAR(_socket_getdefaulttimeout__doc__, +"getdefaulttimeout($module, /)\n" +"--\n" +"\n" +"Return the default timeout in seconds for new socket objects.\n" +"\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."); + +#define _SOCKET_GETDEFAULTTIMEOUT_METHODDEF \ + {"getdefaulttimeout", (PyCFunction)_socket_getdefaulttimeout, METH_NOARGS, _socket_getdefaulttimeout__doc__}, + +static PyObject * +_socket_getdefaulttimeout_impl(PyObject *module); + +static PyObject * +_socket_getdefaulttimeout(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _socket_getdefaulttimeout_impl(module); +} + +PyDoc_STRVAR(_socket_setdefaulttimeout__doc__, +"setdefaulttimeout($module, timeout, /)\n" +"--\n" +"\n" +"Set the default timeout in seconds for new socket objects.\n" +"\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."); + +#define _SOCKET_SETDEFAULTTIMEOUT_METHODDEF \ + {"setdefaulttimeout", (PyCFunction)_socket_setdefaulttimeout, METH_O, _socket_setdefaulttimeout__doc__}, + +#if (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) + +PyDoc_STRVAR(_socket_if_nameindex__doc__, +"if_nameindex($module, /)\n" +"--\n" +"\n" +"Return a list of network interface information (index, name) tuples."); + +#define _SOCKET_IF_NAMEINDEX_METHODDEF \ + {"if_nameindex", (PyCFunction)_socket_if_nameindex, METH_NOARGS, _socket_if_nameindex__doc__}, + +static PyObject * +_socket_if_nameindex_impl(PyObject *module); + +static PyObject * +_socket_if_nameindex(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _socket_if_nameindex_impl(module); +} + +#endif /* (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) */ + #if (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) PyDoc_STRVAR(_socket_if_nametoindex__doc__, @@ -528,14 +2234,223 @@ _socket_if_indextoname(PyObject *module, PyObject *arg) #endif /* (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) */ +#if defined(CMSG_LEN) + +PyDoc_STRVAR(_socket_CMSG_LEN__doc__, +"CMSG_LEN($module, length, /)\n" +"--\n" +"\n" +"Return the total length of an ancillary data item with associated data.\n" +"\n" +"The associated data has the given length. This value can often be\n" +"used as the buffer size for recvmsg() to receive a single item of\n" +"ancillary data, but RFC 3542 requires portable applications to use\n" +"CMSG_SPACE() and thus include space for padding, even when the item\n" +"will be the last in the buffer. Raises OverflowError if length is\n" +"outside the permissible range of values."); + +#define _SOCKET_CMSG_LEN_METHODDEF \ + {"CMSG_LEN", (PyCFunction)_socket_CMSG_LEN, METH_O, _socket_CMSG_LEN__doc__}, + +static PyObject * +_socket_CMSG_LEN_impl(PyObject *module, Py_ssize_t length); + +static PyObject * +_socket_CMSG_LEN(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t length; + + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; + } + return_value = _socket_CMSG_LEN_impl(module, length); + +exit: + return return_value; +} + +#endif /* defined(CMSG_LEN) */ + +#if defined(CMSG_LEN) && defined(CMSG_SPACE) + +PyDoc_STRVAR(_socket_CMSG_SPACE__doc__, +"CMSG_SPACE($module, length, /)\n" +"--\n" +"\n" +"Return the buffer size needed to receive an ancillary data item.\n" +"\n" +"The item has associated data of the given length, and the size\n" +"includes any trailing padding. The buffer space needed to receive\n" +"multiple items is the sum of the CMSG_SPACE() values for their\n" +"associated data lengths. Raises OverflowError if length is outside\n" +"the permissible range of values."); + +#define _SOCKET_CMSG_SPACE_METHODDEF \ + {"CMSG_SPACE", (PyCFunction)_socket_CMSG_SPACE, METH_O, _socket_CMSG_SPACE__doc__}, + +static PyObject * +_socket_CMSG_SPACE_impl(PyObject *module, Py_ssize_t length); + +static PyObject * +_socket_CMSG_SPACE(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t length; + + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; + } + return_value = _socket_CMSG_SPACE_impl(module, length); + +exit: + return return_value; +} + +#endif /* defined(CMSG_LEN) && defined(CMSG_SPACE) */ + +#ifndef _SOCKET_SOCKET__ACCEPT_METHODDEF + #define _SOCKET_SOCKET__ACCEPT_METHODDEF +#endif /* !defined(_SOCKET_SOCKET__ACCEPT_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_BIND_METHODDEF + #define _SOCKET_SOCKET_BIND_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_BIND_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_CONNECT_METHODDEF + #define _SOCKET_SOCKET_CONNECT_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_CONNECT_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_CONNECT_EX_METHODDEF + #define _SOCKET_SOCKET_CONNECT_EX_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_CONNECT_EX_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_GETSOCKNAME_METHODDEF + #define _SOCKET_SOCKET_GETSOCKNAME_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_GETSOCKNAME_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_GETPEERNAME_METHODDEF + #define _SOCKET_SOCKET_GETPEERNAME_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_GETPEERNAME_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_LISTEN_METHODDEF + #define _SOCKET_SOCKET_LISTEN_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_LISTEN_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_RECVFROM_METHODDEF + #define _SOCKET_SOCKET_RECVFROM_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_RECVFROM_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF + #define _SOCKET_SOCKET_RECVFROM_INTO_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_RECVFROM_INTO_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_RECVMSG_METHODDEF + #define _SOCKET_SOCKET_RECVMSG_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_RECVMSG_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF + #define _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_RECVMSG_INTO_METHODDEF) */ + #ifndef _SOCKET_SOCKET_SENDMSG_METHODDEF #define _SOCKET_SOCKET_SENDMSG_METHODDEF #endif /* !defined(_SOCKET_SOCKET_SENDMSG_METHODDEF) */ +#ifndef _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF + #define _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_SHUTDOWN_METHODDEF + #define _SOCKET_SOCKET_SHUTDOWN_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_SHUTDOWN_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_SHARE_METHODDEF + #define _SOCKET_SOCKET_SHARE_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_SHARE_METHODDEF) */ + +#ifndef _SOCKET_GETHOSTNAME_METHODDEF + #define _SOCKET_GETHOSTNAME_METHODDEF +#endif /* !defined(_SOCKET_GETHOSTNAME_METHODDEF) */ + +#ifndef _SOCKET_SETHOSTNAME_METHODDEF + #define _SOCKET_SETHOSTNAME_METHODDEF +#endif /* !defined(_SOCKET_SETHOSTNAME_METHODDEF) */ + +#ifndef _SOCKET_GETHOSTBYNAME_METHODDEF + #define _SOCKET_GETHOSTBYNAME_METHODDEF +#endif /* !defined(_SOCKET_GETHOSTBYNAME_METHODDEF) */ + +#ifndef _SOCKET_GETHOSTBYNAME_EX_METHODDEF + #define _SOCKET_GETHOSTBYNAME_EX_METHODDEF +#endif /* !defined(_SOCKET_GETHOSTBYNAME_EX_METHODDEF) */ + +#ifndef _SOCKET_GETHOSTBYADDR_METHODDEF + #define _SOCKET_GETHOSTBYADDR_METHODDEF +#endif /* !defined(_SOCKET_GETHOSTBYADDR_METHODDEF) */ + +#ifndef _SOCKET_GETSERVBYNAME_METHODDEF + #define _SOCKET_GETSERVBYNAME_METHODDEF +#endif /* !defined(_SOCKET_GETSERVBYNAME_METHODDEF) */ + +#ifndef _SOCKET_GETSERVBYPORT_METHODDEF + #define _SOCKET_GETSERVBYPORT_METHODDEF +#endif /* !defined(_SOCKET_GETSERVBYPORT_METHODDEF) */ + +#ifndef _SOCKET_GETPROTOBYNAME_METHODDEF + #define _SOCKET_GETPROTOBYNAME_METHODDEF +#endif /* !defined(_SOCKET_GETPROTOBYNAME_METHODDEF) */ + +#ifndef _SOCKET_DUP_METHODDEF + #define _SOCKET_DUP_METHODDEF +#endif /* !defined(_SOCKET_DUP_METHODDEF) */ + +#ifndef _SOCKET_SOCKETPAIR_METHODDEF + #define _SOCKET_SOCKETPAIR_METHODDEF +#endif /* !defined(_SOCKET_SOCKETPAIR_METHODDEF) */ + #ifndef _SOCKET_INET_NTOA_METHODDEF #define _SOCKET_INET_NTOA_METHODDEF #endif /* !defined(_SOCKET_INET_NTOA_METHODDEF) */ +#ifndef _SOCKET_INET_PTON_METHODDEF + #define _SOCKET_INET_PTON_METHODDEF +#endif /* !defined(_SOCKET_INET_PTON_METHODDEF) */ + +#ifndef _SOCKET_INET_NTOP_METHODDEF + #define _SOCKET_INET_NTOP_METHODDEF +#endif /* !defined(_SOCKET_INET_NTOP_METHODDEF) */ + +#ifndef _SOCKET_GETADDRINFO_METHODDEF + #define _SOCKET_GETADDRINFO_METHODDEF +#endif /* !defined(_SOCKET_GETADDRINFO_METHODDEF) */ + +#ifndef _SOCKET_GETNAMEINFO_METHODDEF + #define _SOCKET_GETNAMEINFO_METHODDEF +#endif /* !defined(_SOCKET_GETNAMEINFO_METHODDEF) */ + +#ifndef _SOCKET_IF_NAMEINDEX_METHODDEF + #define _SOCKET_IF_NAMEINDEX_METHODDEF +#endif /* !defined(_SOCKET_IF_NAMEINDEX_METHODDEF) */ + #ifndef _SOCKET_IF_NAMETOINDEX_METHODDEF #define _SOCKET_IF_NAMETOINDEX_METHODDEF #endif /* !defined(_SOCKET_IF_NAMETOINDEX_METHODDEF) */ @@ -543,4 +2458,12 @@ _socket_if_indextoname(PyObject *module, PyObject *arg) #ifndef _SOCKET_IF_INDEXTONAME_METHODDEF #define _SOCKET_IF_INDEXTONAME_METHODDEF #endif /* !defined(_SOCKET_IF_INDEXTONAME_METHODDEF) */ -/*[clinic end generated code: output=0b1fa78ac6589353 input=a9049054013a1b77]*/ + +#ifndef _SOCKET_CMSG_LEN_METHODDEF + #define _SOCKET_CMSG_LEN_METHODDEF +#endif /* !defined(_SOCKET_CMSG_LEN_METHODDEF) */ + +#ifndef _SOCKET_CMSG_SPACE_METHODDEF + #define _SOCKET_CMSG_SPACE_METHODDEF +#endif /* !defined(_SOCKET_CMSG_SPACE_METHODDEF) */ +/*[clinic end generated code: output=c96ac95c17326e10 input=a9049054013a1b77]*/ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 73ae1c942daba48..5ae7d832440697c 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3085,11 +3085,21 @@ sock_accept_impl(PySocketSockObject *s, void *data) /* s._accept() -> (fd, address) */ +/*[clinic input] +_socket.socket._accept + self as s: self(type="PySocketSockObject *") + +Wait for an incoming connection. + +Return a new socket file descriptor representing the connection, and +the address of the client. For IP sockets, the address info is a +pair (hostaddr, port). +[clinic start generated code]*/ + static PyObject * -sock_accept(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_socket__accept_impl(PySocketSockObject *s) +/*[clinic end generated code: output=d24eca9a1d4c988e input=07959cdbb2f2a387]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - sock_addr_t addrbuf; SOCKET_T newfd; socklen_t addrlen; @@ -3155,12 +3165,6 @@ sock_accept(PyObject *self, PyObject *Py_UNUSED(ignored)) return NULL; } -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)."); #endif // defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) @@ -3169,8 +3173,21 @@ For IP sockets, the address info is a pair (hostaddr, port)."); True -- blocking mode; same as settimeout(None) */ +/*[clinic input] +_socket.socket.setblocking + self as s: self(type="PySocketSockObject *") + flag as arg: object + / + +Set the socket to blocking (flag is true) or non-blocking (false). + +setblocking(True) is equivalent to settimeout(None); +setblocking(False) is equivalent to settimeout(0.0). +[clinic start generated code]*/ + static PyObject * -sock_setblocking(PyObject *self, PyObject *arg) +_socket_socket_setblocking_impl(PySocketSockObject *s, PyObject *arg) +/*[clinic end generated code: output=39a348904324f352 input=115fee5787faedac]*/ { long block; @@ -3178,7 +3195,6 @@ sock_setblocking(PyObject *self, PyObject *arg) if (block < 0) return NULL; - PySocketSockObject *s = _PySocketSockObject_CAST(self); s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); if (internal_setblocking(s, block) == -1) { return NULL; @@ -3186,21 +3202,22 @@ sock_setblocking(PyObject *self, PyObject *arg) Py_RETURN_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.getblocking() method. Returns True if socket is in blocking mode, False if it is in non-blocking mode. */ +/*[clinic input] +_socket.socket.getblocking + self as s: self(type="PySocketSockObject *") + +Return True if socket is in blocking mode, False if in non-blocking. +[clinic start generated code]*/ + static PyObject * -sock_getblocking(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_socket_getblocking_impl(PySocketSockObject *s) +/*[clinic end generated code: output=e760d93dae8b6ef7 input=13dfb70bc40c3cf8]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); if (s->sock_timeout) { Py_RETURN_TRUE; } @@ -3209,11 +3226,6 @@ sock_getblocking(PyObject *self, PyObject *Py_UNUSED(ignored)) } } -PyDoc_STRVAR(getblocking_doc, -"getblocking()\n\ -\n\ -Returns True if socket is in blocking mode, or False if it\n\ -is in non-blocking mode."); static int socket_parse_timeout(PyTime_t *timeout, PyObject *timeout_obj) @@ -3262,15 +3274,29 @@ socket_parse_timeout(PyTime_t *timeout, PyObject *timeout_obj) > 0 -- timeout mode; operations time out after timeout seconds < 0 -- illegal; raises an exception */ +/*[clinic input] +_socket.socket.settimeout + self as s: self(type="PySocketSockObject *") + timeout as arg: object + / + +Set a timeout on socket operations. + +'timeout' can be a float, giving in seconds, or None. Setting a +timeout of None disables the timeout feature and is equivalent to +setblocking(1). Setting a timeout of zero is the same as +setblocking(0). +[clinic start generated code]*/ + static PyObject * -sock_settimeout(PyObject *self, PyObject *arg) +_socket_socket_settimeout_impl(PySocketSockObject *s, PyObject *arg) +/*[clinic end generated code: output=5e57e2e1cba1c234 input=08bc8324b9fdb3f9]*/ { PyTime_t timeout; if (socket_parse_timeout(&timeout, arg) < 0) return NULL; - PySocketSockObject *s = _PySocketSockObject_CAST(self); s->sock_timeout = timeout; int block = timeout < 0; @@ -3301,13 +3327,6 @@ sock_settimeout(PyObject *self, PyObject *arg) Py_RETURN_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. */ @@ -3324,10 +3343,20 @@ sock_gettimeout_impl(PyObject *self, void *Py_UNUSED(ignored)) } } -static inline PyObject * -sock_gettimeout_method(PyObject *self, PyObject *Py_UNUSED(ignored)) +/*[clinic input] +_socket.socket.gettimeout + +Return the timeout in seconds (float) of socket operations. + +A timeout of None indicates that timeouts on socket operations are +disabled. +[clinic start generated code]*/ + +static PyObject * +_socket_socket_gettimeout_impl(PySocketSockObject *self) +/*[clinic end generated code: output=cd49b7758a504532 input=47e7c5bf80e26eaa]*/ { - return sock_gettimeout_impl(self, NULL); + return sock_gettimeout_impl((PyObject *)self, NULL); } static inline PyObject * @@ -3336,12 +3365,6 @@ sock_gettimeout_getter(PyObject *self, void *Py_UNUSED(closure)) return sock_gettimeout_impl(self, NULL); } -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."); #ifdef HAVE_SETSOCKOPT /* s.setsockopt() method. @@ -3483,22 +3506,30 @@ None, optlen."); With a third integer argument, retrieves a string buffer of that size; use optional built-in module 'struct' to decode the string. */ +/*[clinic input] +_socket.socket.getsockopt + self as s: self(type="PySocketSockObject *") + level: int + option as optname: int + buffersize as buflen: int = 0 + / + +Get a socket option. + +See the Unix manual for level and option. If a nonzero buffersize +argument is given, the return value is a bytes object of that +length; otherwise it is an integer. +[clinic start generated code]*/ + static PyObject * -sock_getsockopt(PyObject *self, PyObject *args) +_socket_socket_getsockopt_impl(PySocketSockObject *s, int level, int optname, + int buflen) +/*[clinic end generated code: output=0b397d1e2237a512 input=1a586fad20b3c3fa]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - - int level; - int optname; int res; - socklen_t buflen = 0; int flag = 0; socklen_t flagsize; - if (!PyArg_ParseTuple(args, "ii|i:getsockopt", - &level, &optname, &buflen)) - return NULL; - if (buflen == 0) { #ifdef AF_VSOCK if (s->sock_family == AF_VSOCK) { @@ -3539,31 +3570,38 @@ sock_getsockopt(PyObject *self, PyObject *args) if (writer == NULL) { return NULL; } + socklen_t optlen = buflen; res = getsockopt(get_sock_fd(s), level, optname, - PyBytesWriter_GetData(writer), &buflen); + PyBytesWriter_GetData(writer), &optlen); if (res < 0) { PyBytesWriter_Discard(writer); return s->errorhandler(); } - return PyBytesWriter_FinishWithSize(writer, buflen); + return PyBytesWriter_FinishWithSize(writer, optlen); } -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."); #ifdef HAVE_BIND /* s.bind(sockaddr) method */ +/*[clinic input] +_socket.socket.bind + self as s: self(type="PySocketSockObject *") + address as addro: object + / + +Bind the socket to a local address. + +For IP sockets, the address is a pair (host, port); the host must +refer to the local host. For raw packet sockets the address is a +tuple (ifname, proto [,pkttype [,hatype [,addr]]]). +[clinic start generated code]*/ + static PyObject * -sock_bind(PyObject *self, PyObject *addro) +_socket_socket_bind_impl(PySocketSockObject *s, PyObject *addro) +/*[clinic end generated code: output=b8d74d0184a9f187 input=ee3f536adbaaa1cb]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - sock_addr_t addrbuf; int addrlen; int res; @@ -3584,12 +3622,6 @@ sock_bind(PyObject *self, PyObject *addro) Py_RETURN_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 [,addr]]])"); #endif @@ -3633,21 +3665,25 @@ _socket_socket_close_impl(PySocketSockObject *s) Py_RETURN_NONE; } +/*[clinic input] +_socket.socket.detach + self as s: self(type="PySocketSockObject *") + +Close the socket object without closing the 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. +[clinic start generated code]*/ + static PyObject * -sock_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_socket_detach_impl(PySocketSockObject *s) +/*[clinic end generated code: output=769cc72d7fdddebd input=ee1305f0594b88cc]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); SOCKET_T fd = get_sock_fd(s); set_sock_fd(s, INVALID_SOCKET); 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."); #ifdef HAVE_CONNECT static int @@ -3751,11 +3787,21 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, /* s.connect(sockaddr) method */ +/*[clinic input] +_socket.socket.connect + self as s: self(type="PySocketSockObject *") + address as addro: object + / + +Connect the socket to a remote address. + +For IP sockets, the address is a pair (host, port). +[clinic start generated code]*/ + static PyObject * -sock_connect(PyObject *self, PyObject *addro) +_socket_socket_connect_impl(PySocketSockObject *s, PyObject *addro) +/*[clinic end generated code: output=d4f73817eb43ed12 input=1b7c601416490538]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - sock_addr_t addrbuf; int addrlen; int res; @@ -3777,20 +3823,26 @@ sock_connect(PyObject *self, PyObject *addro) Py_RETURN_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 */ +/*[clinic input] +_socket.socket.connect_ex + self as s: self(type="PySocketSockObject *") + address as addro: object + / + +Connect the socket to a remote address. + +This is like connect(address), but returns an error code (the errno +value) instead of raising an exception when an error occurs. +[clinic start generated code]*/ + static PyObject * -sock_connect_ex(PyObject *self, PyObject *addro) +_socket_socket_connect_ex_impl(PySocketSockObject *s, PyObject *addro) +/*[clinic end generated code: output=bc8b7cdf80e419af input=716f3a78a296d7ca]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - sock_addr_t addrbuf; int addrlen; int res; @@ -3811,37 +3863,45 @@ sock_connect_ex(PyObject *self, PyObject *addro) 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."); #endif // HAVE_CONNECT /* s.fileno() method */ +/*[clinic input] +_socket.socket.fileno + self as s: self(type="PySocketSockObject *") + +Return the integer file descriptor of the socket. +[clinic start generated code]*/ + static PyObject * -sock_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_socket_fileno_impl(PySocketSockObject *s) +/*[clinic end generated code: output=6d422560f508d2c6 input=7f817a2413c3c37c]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); return PyLong_FromSocket_t(get_sock_fd(s)); } -PyDoc_STRVAR(fileno_doc, -"fileno() -> integer\n\ -\n\ -Return the integer file descriptor of the socket."); #ifdef HAVE_GETSOCKNAME /* s.getsockname() method */ +/*[clinic input] +_socket.socket.getsockname + self as s: self(type="PySocketSockObject *") + +Return the address of the local endpoint. + +The format depends on the address family. For IPv4 sockets, the +address info is a pair (hostaddr, port). For IPv6 sockets, the +address info is a 4-tuple (hostaddr, port, flowinfo, scope_id). +[clinic start generated code]*/ + static PyObject * -sock_getsockname(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_socket_getsockname_impl(PySocketSockObject *s) +/*[clinic end generated code: output=b4c94874b6bf20ed input=b6628802847b2eef]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - sock_addr_t addrbuf; int res; socklen_t addrlen; @@ -3858,24 +3918,25 @@ sock_getsockname(PyObject *self, PyObject *Py_UNUSED(ignored)) s->sock_proto); } -PyDoc_STRVAR(getsockname_doc, -"getsockname() -> address info\n\ -\n\ -Return the address of the local endpoint. The format depends on the\n\ -address family. For IPv4 sockets, the address info is a pair\n\ -(hostaddr, port). For IPv6 sockets, the address info is a 4-tuple\n\ -(hostaddr, port, flowinfo, scope_id)."); #endif #ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */ /* s.getpeername() method */ +/*[clinic input] +_socket.socket.getpeername + self as s: self(type="PySocketSockObject *") + +Return the address of the remote endpoint. + +For IP sockets, the address info is a pair (hostaddr, port). +[clinic start generated code]*/ + static PyObject * -sock_getpeername(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_socket_getpeername_impl(PySocketSockObject *s) +/*[clinic end generated code: output=3e20211d74c8f60b input=aa6b96e92c7996be]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - sock_addr_t addrbuf; int res; socklen_t addrlen; @@ -3892,11 +3953,6 @@ sock_getpeername(PyObject *self, PyObject *Py_UNUSED(ignored)) 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)."); #endif /* HAVE_GETPEERNAME */ @@ -3904,18 +3960,26 @@ info is a pair (hostaddr, port)."); #ifdef HAVE_LISTEN /* s.listen(n) method */ +/*[clinic input] +_socket.socket.listen + self as s: self(type="PySocketSockObject *") + backlog: int(c_default="Py_MIN(SOMAXCONN, 128)") = min(SOMAXCONN, 128) + / + +Enable a server to accept connections. + +If backlog is specified, it must be at least 0 (if it is lower, it +is set to 0); it specifies the number of unaccepted connections that +the system will allow before refusing new connections. If not +specified, a default reasonable value is chosen. +[clinic start generated code]*/ + static PyObject * -sock_listen(PyObject *self, PyObject *args) +_socket_socket_listen_impl(PySocketSockObject *s, int backlog) +/*[clinic end generated code: output=245718576af7f07b input=8eb794d108797ad9]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - /* We try to choose a default backlog high enough to avoid connection drops - * for common workloads, yet not too high to limit resource usage. */ - int backlog = Py_MIN(SOMAXCONN, 128); int res; - if (!PyArg_ParseTuple(args, "|i:listen", &backlog)) - 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. */ @@ -3928,13 +3992,6 @@ sock_listen(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(listen_doc, -"listen([backlog])\n\ -\n\ -Enable a server to accept connections. If backlog is specified, it must be\n\ -at 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. If not specified, a default reasonable value is chosen."); #endif struct sock_recv { @@ -3995,16 +4052,27 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) /* s.recv(nbytes [,flags]) method */ -static PyObject * -sock_recv(PyObject *self, PyObject *args) -{ - PySocketSockObject *s = _PySocketSockObject_CAST(self); +/*[clinic input] +_socket.socket.recv + self as s: self(type="PySocketSockObject *") + buffersize as recvlen: Py_ssize_t + flags: int = 0 + / - Py_ssize_t recvlen, outlen; - int flags = 0; +Receive up to buffersize bytes from the socket. - if (!PyArg_ParseTuple(args, "n|i:recv", &recvlen, &flags)) - return NULL; +For the optional flags argument, see the Unix manual. When no data +is available, block until at least one byte is available or until +the remote end is closed. When the remote end is closed and all data +is read, return the empty string. +[clinic start generated code]*/ + +static PyObject * +_socket_socket_recv_impl(PySocketSockObject *s, Py_ssize_t recvlen, + int flags) +/*[clinic end generated code: output=412b46af1a68ee75 input=6c8382200e8f85fc]*/ +{ + Py_ssize_t outlen; if (recvlen < 0) { PyErr_SetString(PyExc_ValueError, @@ -4030,37 +4098,34 @@ sock_recv(PyObject *self, PyObject *args) return PyBytesWriter_FinishWithSize(writer, outlen); } -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(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; - PySocketSockObject *s = _PySocketSockObject_CAST(self); +/*[clinic input] +_socket.socket.recv_into + self as s: self(type="PySocketSockObject *") + buffer as pbuf: Py_buffer(accept={rwbuffer}) + nbytes as recvlen: Py_ssize_t = 0 + flags: int = 0 - int flags = 0; - Py_buffer pbuf; - char *buf; - Py_ssize_t buflen, readlen, recvlen = 0; +Receive up to nbytes bytes from the socket, storing into a buffer. - /* Get the buffer's memory */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recv_into", kwlist, - &pbuf, &recvlen, &flags)) - return NULL; - buf = pbuf.buf; - buflen = pbuf.len; +A version of recv() that stores its data into a buffer rather than +creating a new bytes object. If nbytes is not specified (or 0), +receive up to the size available in the given buffer. + +See recv() for documentation about the flags. +[clinic start generated code]*/ + +static PyObject * +_socket_socket_recv_into_impl(PySocketSockObject *s, Py_buffer *pbuf, + Py_ssize_t recvlen, int flags) +/*[clinic end generated code: output=58a1cbe9fadb88d7 input=410e6aff36c416a0]*/ +{ + char *buf = pbuf->buf; + Py_ssize_t buflen = pbuf->len, readlen; if (recvlen < 0) { - PyBuffer_Release(&pbuf); PyErr_SetString(PyExc_ValueError, "negative buffersize in recv_into"); return NULL; @@ -4072,7 +4137,6 @@ sock_recv_into(PyObject *self, PyObject *args, PyObject *kwds) /* Check if the buffer is large enough */ if (buflen < recvlen) { - PyBuffer_Release(&pbuf); PyErr_SetString(PyExc_ValueError, "buffer too small for requested bytes"); return NULL; @@ -4082,24 +4146,14 @@ sock_recv_into(PyObject *self, PyObject *args, PyObject *kwds) readlen = sock_recv_guts(s, buf, recvlen, 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."); struct sock_recvfrom { char* cbuf; @@ -4178,17 +4232,26 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, /* s.recvfrom(nbytes [,flags]) method */ +/*[clinic input] +_socket.socket.recvfrom + self as s: self(type="PySocketSockObject *") + buffersize as recvlen: Py_ssize_t + flags: int = 0 + / + +Receive up to buffersize bytes and the sender's address info. + +Like recv(buffersize, flags), but return a (data, address info) +pair. +[clinic start generated code]*/ + static PyObject * -sock_recvfrom(PyObject *self, PyObject *args) +_socket_socket_recvfrom_impl(PySocketSockObject *s, Py_ssize_t recvlen, + int flags) +/*[clinic end generated code: output=52b2ece9ea4251b1 input=d8c8c5dc56c02e86]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - PyObject *addr = NULL; - int flags = 0; - Py_ssize_t recvlen, outlen; - - if (!PyArg_ParseTuple(args, "n|i:recvfrom", &recvlen, &flags)) - return NULL; + Py_ssize_t outlen; if (recvlen < 0) { PyErr_SetString(PyExc_ValueError, @@ -4220,36 +4283,33 @@ sock_recvfrom(PyObject *self, PyObject *args) return NULL; } -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(PyObject *self, PyObject *args, PyObject* kwds) -{ - static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; - PySocketSockObject *s = _PySocketSockObject_CAST(self); +/*[clinic input] +_socket.socket.recvfrom_into + self as s: self(type="PySocketSockObject *") + buffer as pbuf: Py_buffer(accept={rwbuffer}) + nbytes as recvlen: Py_ssize_t = 0 + flags: int = 0 - int flags = 0; - Py_buffer pbuf; - char *buf; - Py_ssize_t readlen, buflen, recvlen = 0; +Receive up to nbytes bytes and the sender's address info. - PyObject *addr = NULL; +Like recv_into(buffer, nbytes, flags), but return a (nbytes, address +info) pair. +[clinic start generated code]*/ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recvfrom_into", - kwlist, &pbuf, - &recvlen, &flags)) - return NULL; - buf = pbuf.buf; - buflen = pbuf.len; +static PyObject * +_socket_socket_recvfrom_into_impl(PySocketSockObject *s, Py_buffer *pbuf, + Py_ssize_t recvlen, int flags) +/*[clinic end generated code: output=e60b491a1c9d5bec input=2a15bf437b8b98ba]*/ +{ + char *buf = pbuf->buf; + Py_ssize_t readlen, buflen = pbuf->len; + PyObject *addr = NULL; if (recvlen < 0) { - PyBuffer_Release(&pbuf); PyErr_SetString(PyExc_ValueError, "negative buffersize in recvfrom_into"); return NULL; @@ -4258,7 +4318,6 @@ sock_recvfrom_into(PyObject *self, PyObject *args, PyObject* kwds) /* 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; @@ -4266,22 +4325,16 @@ sock_recvfrom_into(PyObject *self, PyObject *args, PyObject* kwds) readlen = sock_recvfrom_guts(s, buf, recvlen, 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."); #endif /* The sendmsg() and recvmsg[_into]() methods require a working @@ -4456,14 +4509,47 @@ makeval_recvmsg(ssize_t received, void *data) /* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */ +/*[clinic input] +_socket.socket.recvmsg + self as s: self(type="PySocketSockObject *") + bufsize: Py_ssize_t + ancbufsize: Py_ssize_t = 0 + flags: int = 0 + / + +Receive normal data and ancillary data from the socket. + +Receive up to bufsize bytes of normal data. 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 the +SCM_RIGHTS mechanism. +[clinic start generated code]*/ + static PyObject * -sock_recvmsg(PyObject *self, PyObject *args) +_socket_socket_recvmsg_impl(PySocketSockObject *s, Py_ssize_t bufsize, + Py_ssize_t ancbufsize, int flags) +/*[clinic end generated code: output=1a26c130cf1a898f input=ae53e29436e6c0a3]*/ { - Py_ssize_t bufsize, ancbufsize = 0; - int flags = 0; - 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; @@ -4481,41 +4567,12 @@ sock_recvmsg(PyObject *self, PyObject *args) writer (&writer); makeval_recvmsg() finish it and set our pointer to NULL. */ PyObject *retval; - PySocketSockObject *s = _PySocketSockObject_CAST(self); retval = sock_recvmsg_guts(s, &iov, 1, flags, ancbufsize, &makeval_recvmsg, &writer); PyBytesWriter_Discard(writer); 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 * @@ -4526,21 +4583,55 @@ makeval_recvmsg_into(ssize_t received, void *data) /* s.recvmsg_into(buffers[, ancbufsize[, flags]]) method */ +/*[clinic input] +_socket.socket.recvmsg_into + self as s: self(type="PySocketSockObject *") + buffers as buffers_arg: object + ancbufsize: Py_ssize_t = 0 + flags: int = 0 + / + +Receive normal and ancillary data, scattering the normal data. + +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 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: (nbytes, ancdata, msg_flags, +address). The nbytes item is the total number of bytes of +non-ancillary data written into the buffers. 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_into() raises an exception after the system call returns, +it will first attempt to close any file descriptors received via the +SCM_RIGHTS mechanism. +[clinic start generated code]*/ + static PyObject * -sock_recvmsg_into(PyObject *self, PyObject *args) +_socket_socket_recvmsg_into_impl(PySocketSockObject *s, + PyObject *buffers_arg, + Py_ssize_t ancbufsize, int flags) +/*[clinic end generated code: output=282fd7dd1bdb15f8 input=427536a5043122d2]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - - Py_ssize_t ancbufsize = 0; - int flags = 0; struct iovec *iovs = NULL; Py_ssize_t i, nitems, nbufs = 0; Py_buffer *bufs = NULL; - PyObject *buffers_arg, *buffers_tuple, *retval = NULL; - - if (!PyArg_ParseTuple(args, "O|ni:recvmsg_into", - &buffers_arg, &ancbufsize, &flags)) - return NULL; + PyObject *buffers_tuple, *retval = NULL; buffers_tuple = PySequence_Tuple(buffers_arg); if (buffers_tuple == NULL) { @@ -4582,38 +4673,6 @@ sock_recvmsg_into(PyObject *self, PyObject *args) 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 */ @@ -5140,27 +5199,37 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, #endif /* CMSG_LEN */ #ifdef HAVE_SOCKADDR_ALG -static PyObject* -sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) -{ - PySocketSockObject *self = _PySocketSockObject_CAST(s); +/*[clinic input] +_socket.socket.sendmsg_afalg + self: self(type="PySocketSockObject *") + msg as data_arg: object = NULL + * + op as opobj: object(subclass_of='&PyLong_Type') = NULL + iv: Py_buffer = NULL + assoclen as assoclenobj: object(subclass_of='&PyLong_Type') = NULL + flags: int = 0 + +Set operation mode, IV and associated data length. + +For an AF_ALG operation socket. +[clinic start generated code]*/ +static PyObject * +_socket_socket_sendmsg_afalg_impl(PySocketSockObject *self, + PyObject *data_arg, PyObject *opobj, + Py_buffer *iv, PyObject *assoclenobj, + int flags) +/*[clinic end generated code: output=3fd9856d4d9f7c97 input=3ed371da034a1bb3]*/ +{ PyObject *retval = NULL; Py_ssize_t i, ndatabufs = 0; Py_buffer *databufs = NULL; - PyObject *data_arg = NULL; - Py_buffer iv = {NULL, NULL}; - - PyObject *opobj = NULL; int op = -1; - - PyObject *assoclenobj = NULL; int assoclen = -1; unsigned int *uiptr; - int flags = 0; struct msghdr msg; struct cmsghdr *header = NULL; @@ -5168,7 +5237,6 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) struct sock_sendmsg ctx; Py_ssize_t controllen; void *controlbuf = NULL; - static char *keywords[] = {"msg", "op", "iv", "assoclen", "flags", 0}; if (self->sock_family != AF_ALG) { PyErr_SetString(PyExc_OSError, @@ -5176,14 +5244,6 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) return NULL; } - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|O$O!y*O!i:sendmsg_afalg", keywords, - &data_arg, - &PyLong_Type, &opobj, &iv, - &PyLong_Type, &assoclenobj, &flags)) { - return NULL; - } - memset(&msg, 0, sizeof(msg)); /* op is a required, keyword-only argument >= 0 */ @@ -5210,8 +5270,8 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) } controllen = CMSG_SPACE(4); - if (iv.buf != NULL) { - controllen += CMSG_SPACE(sizeof(*alg_iv) + iv.len); + if (iv->buf != NULL) { + controllen += CMSG_SPACE(sizeof(*alg_iv) + iv->len); } if (assoclen >= 0) { controllen += CMSG_SPACE(4); @@ -5249,7 +5309,7 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) *uiptr = (unsigned int)op; /* set initialization vector */ - if (iv.buf != NULL) { + if (iv->buf != NULL) { header = CMSG_NXTHDR(&msg, header); if (header == NULL) { PyErr_SetString(PyExc_RuntimeError, @@ -5258,10 +5318,10 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) } header->cmsg_level = SOL_ALG; header->cmsg_type = ALG_SET_IV; - header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv.len); + header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv->len); alg_iv = (void*)CMSG_DATA(header); - alg_iv->ivlen = iv.len; - memcpy(alg_iv->iv, iv.buf, iv.len); + alg_iv->ivlen = iv->len; + memcpy(alg_iv->iv, iv->buf, iv->len); } /* set length of associated data for AEAD */ @@ -5289,9 +5349,8 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) finally: PyMem_Free(controlbuf); - if (iv.buf != NULL) { - PyBuffer_Release(&iv); - } + if (iv->buf != NULL) { + } PyMem_Free(msg.msg_iov); for (i = 0; i < ndatabufs; i++) { PyBuffer_Release(&databufs[i]); @@ -5300,21 +5359,28 @@ sock_sendmsg_afalg(PyObject *s, PyObject *args, PyObject *kwds) return retval; } -PyDoc_STRVAR(sendmsg_afalg_doc, -"sendmsg_afalg([msg], *, op[, iv[, assoclen[, flags=MSG_MORE]]])\n\ -\n\ -Set operation mode, IV and length of associated data for an AF_ALG\n\ -operation socket."); #endif #ifdef HAVE_SHUTDOWN /* s.shutdown(how) method */ +/*[clinic input] +_socket.socket.shutdown + self as s: self(type="PySocketSockObject *") + flag as arg: object + / + +Shut down one or both halves of the connection. + +Shut down the reading side of the socket (flag == SHUT_RD), the +writing side of the socket (flag == SHUT_WR), or both ends (flag == +SHUT_RDWR). +[clinic start generated code]*/ + static PyObject * -sock_shutdown(PyObject *self, PyObject *arg) +_socket_socket_shutdown_impl(PySocketSockObject *s, PyObject *arg) +/*[clinic end generated code: output=84264513a6049ca7 input=a90afb227247ce03]*/ { - PySocketSockObject *s = _PySocketSockObject_CAST(self); - int how; int res; @@ -5329,11 +5395,6 @@ sock_shutdown(PyObject *self, PyObject *arg) Py_RETURN_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)."); #endif #if defined(MS_WINDOWS) && defined(SIO_RCVALL) @@ -5395,18 +5456,26 @@ SIO_LOOPBACK_FAST_PATH: 'option' is a boolean value, and is disabled by default" #endif #if defined(MS_WINDOWS) -static PyObject* -sock_share(PyObject *self, PyObject *arg) -{ - PySocketSockObject *s = _PySocketSockObject_CAST(self); +/*[clinic input] +_socket.socket.share + self as s: self(type="PySocketSockObject *") + process_id as processId: unsigned_int(bitwise=True) + / + +Share the socket with another process. +The target process id must be provided and the resulting bytes +object passed to the target process. There the shared socket can be +instantiated by calling socket.fromshare(). +[clinic start generated code]*/ + +static PyObject * +_socket_socket_share_impl(PySocketSockObject *s, unsigned int processId) +/*[clinic end generated code: output=446bfcc5fe3273c6 input=0a9d7536371bfe2d]*/ +{ WSAPROTOCOL_INFOW info; - DWORD processId; int result; - if (!PyArg_ParseTuple(arg, "I", &processId)) - return NULL; - Py_BEGIN_ALLOW_THREADS result = WSADuplicateSocketW(get_sock_fd(s), processId, &info); Py_END_ALLOW_THREADS @@ -5414,13 +5483,6 @@ sock_share(PyObject *self, PyObject *arg) 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 @@ -5429,81 +5491,53 @@ socket.fromshare()."); static PyMethodDef sock_methods[] = { #if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) - {"_accept", sock_accept, METH_NOARGS, accept_doc}, + _SOCKET_SOCKET__ACCEPT_METHODDEF #endif #ifdef HAVE_BIND - {"bind", sock_bind, METH_O, bind_doc}, + _SOCKET_SOCKET_BIND_METHODDEF #endif _SOCKET_SOCKET_CLOSE_METHODDEF #ifdef HAVE_CONNECT - {"connect", sock_connect, METH_O, connect_doc}, - {"connect_ex", sock_connect_ex, METH_O, connect_ex_doc}, + _SOCKET_SOCKET_CONNECT_METHODDEF + _SOCKET_SOCKET_CONNECT_EX_METHODDEF #endif - {"detach", sock_detach, METH_NOARGS, detach_doc}, - {"fileno", sock_fileno, METH_NOARGS, fileno_doc}, + _SOCKET_SOCKET_DETACH_METHODDEF + _SOCKET_SOCKET_FILENO_METHODDEF #ifdef HAVE_GETPEERNAME - {"getpeername", sock_getpeername, METH_NOARGS, getpeername_doc}, + _SOCKET_SOCKET_GETPEERNAME_METHODDEF #endif #ifdef HAVE_GETSOCKNAME - {"getsockname", sock_getsockname, METH_NOARGS, getsockname_doc}, + _SOCKET_SOCKET_GETSOCKNAME_METHODDEF #endif - {"getsockopt", sock_getsockopt, METH_VARARGS, getsockopt_doc}, + _SOCKET_SOCKET_GETSOCKOPT_METHODDEF #if defined(MS_WINDOWS) && defined(SIO_RCVALL) {"ioctl", sock_ioctl, METH_VARARGS, sock_ioctl_doc}, #endif -#if defined(MS_WINDOWS) - {"share", sock_share, METH_VARARGS, sock_share_doc}, -#endif -#ifdef HAVE_LISTEN - {"listen", sock_listen, METH_VARARGS, listen_doc}, -#endif - {"recv", sock_recv, METH_VARARGS, recv_doc}, - { - "recv_into", - _PyCFunction_CAST(sock_recv_into), - METH_VARARGS | METH_KEYWORDS, - recv_into_doc - }, -#ifdef HAVE_RECVFROM - {"recvfrom", sock_recvfrom, METH_VARARGS, recvfrom_doc}, - { - "recvfrom_into", - _PyCFunction_CAST(sock_recvfrom_into), - METH_VARARGS | METH_KEYWORDS, - recvfrom_into_doc - }, -#endif + _SOCKET_SOCKET_SHARE_METHODDEF + _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 #ifdef HAVE_SENDTO {"sendto", sock_sendto, METH_VARARGS, sendto_doc}, #endif - {"setblocking", sock_setblocking, METH_O, setblocking_doc}, - {"getblocking", sock_getblocking, METH_NOARGS, getblocking_doc}, - {"settimeout", sock_settimeout, METH_O, settimeout_doc}, - { - "gettimeout", sock_gettimeout_method, METH_NOARGS, - gettimeout_doc - }, + _SOCKET_SOCKET_SETBLOCKING_METHODDEF + _SOCKET_SOCKET_GETBLOCKING_METHODDEF + _SOCKET_SOCKET_SETTIMEOUT_METHODDEF + _SOCKET_SOCKET_GETTIMEOUT_METHODDEF #ifdef HAVE_SETSOCKOPT {"setsockopt", sock_setsockopt, METH_VARARGS, setsockopt_doc}, #endif #ifdef HAVE_SHUTDOWN - {"shutdown", sock_shutdown, METH_O, shutdown_doc}, + _SOCKET_SOCKET_SHUTDOWN_METHODDEF #endif -#ifdef CMSG_LEN - {"recvmsg", sock_recvmsg, METH_VARARGS, recvmsg_doc}, - {"recvmsg_into", sock_recvmsg_into, METH_VARARGS, recvmsg_into_doc}, + _SOCKET_SOCKET_RECVMSG_METHODDEF + _SOCKET_SOCKET_RECVMSG_INTO_METHODDEF _SOCKET_SOCKET_SENDMSG_METHODDEF -#endif -#ifdef HAVE_SOCKADDR_ALG - { - "sendmsg_afalg", - _PyCFunction_CAST(sock_sendmsg_afalg), - METH_VARARGS | METH_KEYWORDS, - sendmsg_afalg_doc - }, -#endif + _SOCKET_SOCKET_SENDMSG_AFALG_METHODDEF {NULL, NULL, 0, NULL} /* sentinel */ }; @@ -5882,8 +5916,15 @@ static PyType_Spec sock_spec = { /* Python interface to gethostname(). */ /*ARGSUSED*/ +/*[clinic input] +_socket.gethostname + +Return the current host name. +[clinic start generated code]*/ + static PyObject * -socket_gethostname(PyObject *self, PyObject *unused) +_socket_gethostname_impl(PyObject *module) +/*[clinic end generated code: output=1d9b789d69464c01 input=994028f092f41baf]*/ { if (PySys_Audit("socket.gethostname", NULL) < 0) { return NULL; @@ -5939,21 +5980,23 @@ socket_gethostname(PyObject *self, PyObject *unused) #endif } -PyDoc_STRVAR(gethostname_doc, -"gethostname() -> string\n\ -\n\ -Return the current host name."); #endif #ifdef HAVE_SETHOSTNAME -PyDoc_STRVAR(sethostname_doc, -"sethostname(name)\n\n\ -Sets the hostname to name."); + +/*[clinic input] +_socket.sethostname + + name as hnobj: object + / + +Set the hostname to name. +[clinic start generated code]*/ static PyObject * -socket_sethostname(PyObject *self, PyObject *args) +_socket_sethostname(PyObject *module, PyObject *hnobj) +/*[clinic end generated code: output=0b789350cbbc4553 input=89c1a7022cb1082a]*/ { - PyObject *hnobj; Py_buffer buf; int res, flag = 0; @@ -5963,15 +6006,16 @@ socket_sethostname(PyObject *self, PyObject *args) extern int sethostname(const char *, size_t); #endif - if (!PyArg_ParseTuple(args, "S:sethostname", &hnobj)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&:sethostname", - PyUnicode_FSConverter, &hnobj)) + if (!PyBytes_Check(hnobj)) { + if (!PyUnicode_FSConverter(hnobj, &hnobj)) { return NULL; + } flag = 1; } if (PySys_Audit("socket.sethostname", "(O)", hnobj) < 0) { + if (flag) + Py_DECREF(hnobj); return NULL; } @@ -5992,19 +6036,32 @@ extern int sethostname(const char *, size_t); /* Python interface to gethostbyname(name). */ /*ARGSUSED*/ +/*[clinic input] +_socket.gethostbyname + + host as hobj: object + / + +Return the IP address for a host. + +The address is a string of the form '255.255.255.255'. +[clinic start generated code]*/ + static PyObject * -socket_gethostbyname(PyObject *self, PyObject *args) +_socket_gethostbyname(PyObject *module, PyObject *hobj) +/*[clinic end generated code: output=19f571343780c48b input=3c0d3b92e44a1795]*/ { - char *name; struct sockaddr_in addrbuf; + char *name; PyObject *ret = NULL; - if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) + if (!PyArg_Parse(hobj, "et:gethostbyname", "idna", &name)) { return NULL; - if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { + } + if (PySys_Audit("socket.gethostbyname", "(O)", hobj) < 0) { goto finally; } - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); int rc = setipaddr(state, name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET); if (rc < 0) { @@ -6015,11 +6072,6 @@ socket_gethostbyname(PyObject *self, PyObject *args) PyMem_Free(name); 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."); #endif @@ -6184,8 +6236,21 @@ gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr, /* Python interface to gethostbyname_ex(name). */ /*ARGSUSED*/ +/*[clinic input] +_socket.gethostbyname_ex + + host as hobj: object + / + +Map a host name to its IP number. + +Return the true host name, a list of aliases, and a list of IP +addresses, which are strings of the form '255.255.255.255'. +[clinic start generated code]*/ + static PyObject * -socket_gethostbyname_ex(PyObject *self, PyObject *args) +_socket_gethostbyname_ex(PyObject *module, PyObject *hobj) +/*[clinic end generated code: output=a1ea4607d257756e input=1ee9eb485339c58b]*/ { char *name; struct hostent *h; @@ -6206,12 +6271,13 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) #endif #endif /* HAVE_GETHOSTBYNAME_R */ - if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name)) + if (!PyArg_Parse(hobj, "et:gethostbyname_ex", "idna", &name)) { return NULL; - if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { + } + if (PySys_Audit("socket.gethostbyname", "(O)", hobj) < 0) { goto finally; } - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); if (setipaddr(state, name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) { goto finally; } @@ -6252,23 +6318,32 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) 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."); #endif #if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR) /* Python interface to gethostbyaddr(IP). */ /*ARGSUSED*/ +/*[clinic input] +_socket.gethostbyaddr + + host as hobj: object + / + +Map an IP number or host name to the true host name and addresses. + +Return the true host name, a list of aliases, and a list of IP +addresses. The host argument is a string giving a host name or IP +number. +[clinic start generated code]*/ + static PyObject * -socket_gethostbyaddr(PyObject *self, PyObject *args) +_socket_gethostbyaddr(PyObject *module, PyObject *hobj) +/*[clinic end generated code: output=4ba6c4d7a3085ab5 input=c602ba97bf0d395b]*/ { + char *ip_num; sock_addr_t addr; struct sockaddr *sa = SAS2SA(&addr); - char *ip_num; struct hostent *h; PyObject *ret = NULL; #ifdef HAVE_GETHOSTBYNAME_R @@ -6292,13 +6367,14 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) int al; int af; - if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num)) + if (!PyArg_Parse(hobj, "et:gethostbyaddr", "idna", &ip_num)) { return NULL; - if (PySys_Audit("socket.gethostbyaddr", "O", args) < 0) { + } + if (PySys_Audit("socket.gethostbyaddr", "(O)", hobj) < 0) { goto finally; } af = AF_UNSPEC; - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); if (setipaddr(state, ip_num, sa, sizeof(addr), af) < 0) { goto finally; } @@ -6349,15 +6425,8 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) PyMutex_Unlock(&netdb_lock); #endif finally: - PyMem_Free(ip_num); 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."); #endif #ifdef HAVE_GETSERVBYNAME @@ -6366,13 +6435,25 @@ for a host. The host argument is a string giving a host name or IP number."); known or not useful (like the list of aliases). */ /*ARGSUSED*/ +/*[clinic input] +_socket.getservbyname + + servicename as name: str + protocolname as proto: str = NULL + / + +Return a port number from a service name and protocol name. + +The optional protocol name, if given, should be 'tcp' or 'udp', +otherwise any protocol will match. +[clinic start generated code]*/ + static PyObject * -socket_getservbyname(PyObject *self, PyObject *args) +_socket_getservbyname_impl(PyObject *module, const char *name, + const char *proto) +/*[clinic end generated code: output=b0c47287f8ec2b00 input=a8e3ad7ced8c8798]*/ { - const char *name, *proto=NULL; struct servent *sp; - if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto)) - return NULL; if (PySys_Audit("socket.getservbyname", "ss", name, proto) < 0) { return NULL; @@ -6388,12 +6469,6 @@ socket_getservbyname(PyObject *self, PyObject *args) 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."); #endif #ifdef HAVE_GETSERVBYPORT @@ -6402,14 +6477,25 @@ otherwise any protocol will match."); known or not useful (like the list of aliases). */ /*ARGSUSED*/ +/*[clinic input] +_socket.getservbyport + + port: int + protocolname as proto: str = NULL + / + +Return the service name from a port number and protocol name. + +The optional protocol name, if given, should be 'tcp' or 'udp', +otherwise any protocol will match. +[clinic start generated code]*/ + static PyObject * -socket_getservbyport(PyObject *self, PyObject *args) +_socket_getservbyport_impl(PyObject *module, int port, const char *proto) +/*[clinic end generated code: output=42351ab1857aa9e4 input=9a2a3091ea6ff146]*/ { - int port; - const char *proto=NULL; struct servent *sp; - if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto)) - return NULL; + if (port < 0 || port > 0xffff) { PyErr_SetString( PyExc_OverflowError, @@ -6431,12 +6517,6 @@ socket_getservbyport(PyObject *self, PyObject *args) 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."); #endif #ifdef HAVE_GETPROTOBYNAME @@ -6445,13 +6525,20 @@ otherwise any protocol will match."); already known or not useful (like the list of aliases). */ /*ARGSUSED*/ +/*[clinic input] +_socket.getprotobyname + + name: str + / + +Return the protocol number for the named protocol. +[clinic start generated code]*/ + static PyObject * -socket_getprotobyname(PyObject *self, PyObject *args) +_socket_getprotobyname_impl(PyObject *module, const char *name) +/*[clinic end generated code: output=30fb71f0c6ffbaea input=d197d3726c828e38]*/ { - const char *name; struct protoent *sp; - if (!PyArg_ParseTuple(args, "s:getprotobyname", &name)) - return NULL; Py_BEGIN_ALLOW_THREADS sp = getprotobyname(name); Py_END_ALLOW_THREADS @@ -6462,14 +6549,20 @@ socket_getprotobyname(PyObject *self, PyObject *args) 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.)"); #endif +/*[clinic input] +_socket.close + + fd as fdobj: object + / + +Close a socket fd. +[clinic start generated code]*/ + static PyObject * -socket_close(PyObject *self, PyObject *fdobj) +_socket_close(PyObject *module, PyObject *fdobj) +/*[clinic end generated code: output=1d62092e6fc365dc input=3928558b90299147]*/ { SOCKET_T fd; int res; @@ -6488,17 +6581,24 @@ socket_close(PyObject *self, PyObject *fdobj) Py_RETURN_NONE; } -PyDoc_STRVAR(close_doc, -"close(integer) -> None\n\ -\n\ -Close an integer socket file descriptor. This is like os.close(), but for\n\ -sockets; on some platforms os.close() won't work for socket file descriptors."); #ifndef NO_DUP /* dup() function for socket fds */ +/*[clinic input] +_socket.dup + + fd as fdobj: object + / + +Duplicate a socket descriptor. + +The new descriptor is non-inheritable. +[clinic start generated code]*/ + static PyObject * -socket_dup(PyObject *self, PyObject *fdobj) +_socket_dup(PyObject *module, PyObject *fdobj) +/*[clinic end generated code: output=7e9c4485cf5a76c0 input=dfc5de188bf696ef]*/ { SOCKET_T fd, newfd; PyObject *newfdobj; @@ -6542,11 +6642,6 @@ socket_dup(PyObject *self, PyObject *fdobj) 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 @@ -6556,13 +6651,27 @@ sockets; on some platforms os.dup() won't work for socket file descriptors."); defined on the platform; otherwise, the default is AF_INET. */ /*ARGSUSED*/ +/*[clinic input] +_socket.socketpair + + family: int(c_default="AF_UNIX") = AF_UNIX + type: int(c_default="SOCK_STREAM") = SOCK_STREAM + proto: int = 0 + / + +Create a pair of connected socket objects. + +The sockets are returned by the platform socketpair() function. The +arguments are the same as for socket(). +[clinic start generated code]*/ + static PyObject * -socket_socketpair(PyObject *self, PyObject *args) +_socket_socketpair_impl(PyObject *module, int family, int type, int proto) +/*[clinic end generated code: output=c012ae1f558bb0ca input=823902632e78e181]*/ { PySocketSockObject *s0 = NULL, *s1 = NULL; SOCKET_T sv[2]; - int family, type = SOCK_STREAM, proto = 0; - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); #ifdef SOCK_CLOEXEC int *atomic_flag_works = &sock_cloexec_works; #else @@ -6570,15 +6679,6 @@ socket_socketpair(PyObject *self, PyObject *args) #endif int ret; -#if defined(AF_UNIX) - family = AF_UNIX; -#else - family = AF_INET; -#endif - if (!PyArg_ParseTuple(args, "|iii:socketpair", - &family, &type, &proto)) - return NULL; - /* Create a pair of socket fds */ Py_BEGIN_ALLOW_THREADS #ifdef SOCK_CLOEXEC @@ -6628,13 +6728,6 @@ socket_socketpair(PyObject *self, PyObject *args) return NULL; } -PyDoc_STRVAR(socketpair_doc, -"socketpair([family[, type [, proto]]]) -> (socket object, socket object)\n\ -\n\ -Create a pair of socket objects from the sockets returned by the platform\n\ -socketpair() function.\n\ -The arguments are the same as for socket() except the default family is\n\ -AF_UNIX if defined on the platform; otherwise, the default is AF_INET."); #endif /* HAVE_SOCKETPAIR */ @@ -6811,27 +6904,29 @@ _socket_inet_ntoa_impl(PyObject *module, Py_buffer *packed_ip) #ifdef HAVE_INET_PTON -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."); + +/*[clinic input] +_socket.inet_pton + + af: int + ip: str + / + +Convert an IP address from string format to a packed string. + +The string is suitable for use with low-level network functions. +[clinic start generated code]*/ static PyObject * -socket_inet_pton(PyObject *self, PyObject *args) +_socket_inet_pton_impl(PyObject *module, int af, const char *ip) +/*[clinic end generated code: output=a1488ddddc478dc2 input=044acc246469c125]*/ { - int af; - const 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) { PyErr_SetString(PyExc_OSError, @@ -6862,16 +6957,21 @@ socket_inet_pton(PyObject *self, PyObject *args) } } -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."); + +/*[clinic input] +_socket.inet_ntop + + af: int + packed_ip: Py_buffer + / + +Convert a packed IP address of the given family to string format. +[clinic start generated code]*/ static PyObject * -socket_inet_ntop(PyObject *self, PyObject *args) +_socket_inet_ntop_impl(PyObject *module, int af, Py_buffer *packed_ip) +/*[clinic end generated code: output=eabff3e56456ede0 input=7027f0a0abdf71d1]*/ { - int af; - Py_buffer packed_ip; const char* retval; #ifdef ENABLE_IPV6 char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; @@ -6879,43 +6979,33 @@ socket_inet_ntop(PyObject *self, PyObject *args) char ip[INET_ADDRSTRLEN]; #endif - if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) { - return NULL; - } - if (af == AF_INET) { - if (packed_ip.len != sizeof(struct in_addr)) { + if (packed_ip->len != sizeof(struct in_addr)) { PyErr_SetString(PyExc_ValueError, "invalid length of packed IP address string"); - PyBuffer_Release(&packed_ip); return NULL; } #ifdef ENABLE_IPV6 } else if (af == AF_INET6) { - if (packed_ip.len != sizeof(struct in6_addr)) { + if (packed_ip->len != sizeof(struct in6_addr)) { PyErr_SetString(PyExc_ValueError, "invalid length of packed IP address string"); - PyBuffer_Release(&packed_ip); return NULL; } #endif } else { PyErr_Format(PyExc_ValueError, "unknown address family %d", af); - PyBuffer_Release(&packed_ip); return NULL; } /* inet_ntop guarantee NUL-termination of resulting string. */ - retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); + retval = inet_ntop(af, packed_ip->buf, ip, sizeof(ip)); if (!retval) { PyErr_SetFromErrno(PyExc_OSError); - PyBuffer_Release(&packed_ip); return NULL; - } else { - PyBuffer_Release(&packed_ip); - return PyUnicode_FromString(retval); } + return PyUnicode_FromString(retval); } #endif /* HAVE_INET_PTON */ @@ -6924,29 +7014,34 @@ socket_inet_ntop(PyObject *self, PyObject *args) /* Python interface to getaddrinfo(host, port). */ /*ARGSUSED*/ +/*[clinic input] +_socket.getaddrinfo + + host as hobj: object + port as pobj: object + family: int(c_default="AF_UNSPEC") = AF_UNSPEC + type as socktype: int = 0 + proto as protocol: int = 0 + flags: int = 0 + +Resolve host and port into a list of 5-tuples. + +Each tuple is (family, type, proto, canonname, sockaddr). +[clinic start generated code]*/ + static PyObject * -socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) +_socket_getaddrinfo_impl(PyObject *module, PyObject *hobj, PyObject *pobj, + int family, int socktype, int protocol, int flags) +/*[clinic end generated code: output=a54f59f33f3da184 input=1fd64ac89aee1d18]*/ { - static char* kwnames[] = {"host", "port", "family", "type", "proto", - "flags", 0}; struct addrinfo hints, *res; struct addrinfo *res0 = NULL; - PyObject *hobj = NULL; - PyObject *pobj = (PyObject *)NULL; PyObject *pstr = NULL; const 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) { hptr = NULL; } else if (PyUnicode_Check(hobj)) { @@ -7011,7 +7106,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) Py_END_ALLOW_THREADS if (error) { res0 = NULL; // gh-100795 - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); set_gaierror(state, error); goto err; } @@ -7053,22 +7148,26 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) return (PyObject *)NULL; } -PyDoc_STRVAR(getaddrinfo_doc, -"getaddrinfo(host, port [, family, type, proto, flags])\n\ - -> list of (family, type, proto, canonname, sockaddr)\n\ -\n\ -Resolve host and port into addrinfo struct."); #endif // HAVE_GETADDRINFO #ifdef HAVE_GETNAMEINFO /* Python interface to getnameinfo(sa, flags). */ /*ARGSUSED*/ +/*[clinic input] +_socket.getnameinfo + + sockaddr as sa: object + flags: int + / + +Get host and port for a sockaddr. +[clinic start generated code]*/ + static PyObject * -socket_getnameinfo(PyObject *self, PyObject *args) +_socket_getnameinfo_impl(PyObject *module, PyObject *sa, int flags) +/*[clinic end generated code: output=2e1d7ef2bd94f698 input=dd0444ac9adae4d3]*/ { - PyObject *sa = (PyObject *)NULL; - int flags; const char *hostp; int port; unsigned int flowinfo, scope_id; @@ -7078,9 +7177,7 @@ socket_getnameinfo(PyObject *self, PyObject *args) PyObject *ret = (PyObject *)NULL; PyObject *name; - flags = flowinfo = scope_id = 0; - if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags)) - return NULL; + flowinfo = scope_id = 0; if (!PyTuple_Check(sa)) { PyErr_SetString(PyExc_TypeError, "getnameinfo() argument 1 must be a tuple"); @@ -7111,7 +7208,7 @@ socket_getnameinfo(PyObject *self, PyObject *args) Py_END_ALLOW_THREADS if (error) { res = NULL; // gh-100795 - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); set_gaierror(state, error); goto fail; } @@ -7146,7 +7243,7 @@ socket_getnameinfo(PyObject *self, PyObject *args) hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags); Py_END_ALLOW_THREADS if (error) { - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); set_gaierror(state, error); goto fail; } @@ -7162,18 +7259,24 @@ socket_getnameinfo(PyObject *self, PyObject *args) return ret; } -PyDoc_STRVAR(getnameinfo_doc, -"getnameinfo(sockaddr, flags) --> (host, port)\n\ -\n\ -Get host and port for a sockaddr."); #endif // HAVE_GETNAMEINFO /* Python API to getting and setting the default timeout value. */ +/*[clinic input] +_socket.getdefaulttimeout + +Return the default timeout in seconds 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]*/ + static PyObject * -socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) +_socket_getdefaulttimeout_impl(PyObject *module) +/*[clinic end generated code: output=7b3e1be56948c44c input=c9fb729acf998a58]*/ { - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); PyTime_t timeout = _Py_atomic_load_int64_relaxed(&state->defaulttimeout); if (timeout < 0) { Py_RETURN_NONE; @@ -7184,39 +7287,47 @@ socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) } } -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."); + +/*[clinic input] +_socket.setdefaulttimeout + + timeout as arg: object + / + +Set the default timeout in seconds 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]*/ static PyObject * -socket_setdefaulttimeout(PyObject *self, PyObject *arg) +_socket_setdefaulttimeout(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=b5d59296163d66bf input=929785d885173684]*/ { PyTime_t timeout; if (socket_parse_timeout(&timeout, arg) < 0) return NULL; - socket_state *state = get_module_state(self); + socket_state *state = get_module_state(module); _Py_atomic_store_int64_relaxed(&state->defaulttimeout, timeout); Py_RETURN_NONE; } -PyDoc_STRVAR(setdefaulttimeout_doc, -"setdefaulttimeout(timeout)\n\ -\n\ -Set the default timeout in seconds (real number) 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."); #if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) /* Python API for getting interface indices and names */ +/*[clinic input] +_socket.if_nameindex + +Return a list of network interface information (index, name) tuples. +[clinic start generated code]*/ + static PyObject * -socket_if_nameindex(PyObject *self, PyObject *arg) +_socket_if_nameindex_impl(PyObject *module) +/*[clinic end generated code: output=93c863a6262059c4 input=d6438bb556de2100]*/ { PyObject *list = PyList_New(0); if (list == NULL) { @@ -7296,10 +7407,6 @@ socket_if_nameindex(PyObject *self, PyObject *arg) #endif } -PyDoc_STRVAR(if_nameindex_doc, -"if_nameindex()\n\ -\n\ -Returns a list of network interface information (index, name) tuples."); /*[clinic input] _socket.if_nametoindex @@ -7359,14 +7466,28 @@ _socket_if_indextoname_impl(PyObject *module, NET_IFINDEX index) #ifdef CMSG_LEN /* Python interface to CMSG_LEN(length). */ +/*[clinic input] +_socket.CMSG_LEN + + length: Py_ssize_t + / + +Return the total length of an ancillary data item with associated data. + +The associated data has 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]*/ + static PyObject * -socket_CMSG_LEN(PyObject *self, PyObject *args) +_socket_CMSG_LEN_impl(PyObject *module, Py_ssize_t length) +/*[clinic end generated code: output=e1dd6bb3a3f4a7ff input=b0787fd8c8d9c7be]*/ { - Py_ssize_t length; 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; @@ -7374,29 +7495,32 @@ socket_CMSG_LEN(PyObject *self, PyObject *args) 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). */ +/*[clinic input] +_socket.CMSG_SPACE + + length: Py_ssize_t + / + +Return the buffer size needed to receive an ancillary data item. + +The item has associated data of the given length, and the size +includes 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. +[clinic start generated code]*/ + static PyObject * -socket_CMSG_SPACE(PyObject *self, PyObject *args) +_socket_CMSG_SPACE_impl(PyObject *module, Py_ssize_t length) +/*[clinic end generated code: output=857b925dc29c68c3 input=dedf123dcda72642]*/ { - Py_ssize_t length; 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"); @@ -7405,15 +7529,6 @@ socket_CMSG_SPACE(PyObject *self, PyObject *args) 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 */ @@ -7421,88 +7536,40 @@ range of values."); /* List of functions exported by this module. */ static PyMethodDef socket_methods[] = { -#ifdef HAVE_GETADDRINFO - {"gethostbyname", socket_gethostbyname, - METH_VARARGS, gethostbyname_doc}, -#endif -#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME) - {"gethostbyname_ex", socket_gethostbyname_ex, - METH_VARARGS, ghbn_ex_doc}, -#endif -#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR) - {"gethostbyaddr", socket_gethostbyaddr, - METH_VARARGS, gethostbyaddr_doc}, -#endif + _SOCKET_GETHOSTBYNAME_METHODDEF + _SOCKET_GETHOSTBYNAME_EX_METHODDEF + _SOCKET_GETHOSTBYADDR_METHODDEF #ifdef HAVE_GETHOSTNAME - {"gethostname", socket_gethostname, - METH_NOARGS, gethostname_doc}, -#endif -#ifdef HAVE_SETHOSTNAME - {"sethostname", socket_sethostname, - METH_VARARGS, sethostname_doc}, -#endif -#ifdef HAVE_GETSERVBYNAME - {"getservbyname", socket_getservbyname, - METH_VARARGS, getservbyname_doc}, -#endif -#ifdef HAVE_GETSERVBYPORT - {"getservbyport", socket_getservbyport, - METH_VARARGS, getservbyport_doc}, -#endif -#ifdef HAVE_GETPROTOBYNAME - {"getprotobyname", socket_getprotobyname, - METH_VARARGS, getprotobyname_doc}, + _SOCKET_GETHOSTNAME_METHODDEF #endif - {"close", socket_close, - METH_O, close_doc}, + _SOCKET_SETHOSTNAME_METHODDEF + _SOCKET_GETSERVBYNAME_METHODDEF + _SOCKET_GETSERVBYPORT_METHODDEF + _SOCKET_GETPROTOBYNAME_METHODDEF + _SOCKET_CLOSE_METHODDEF #ifndef NO_DUP - {"dup", socket_dup, - METH_O, dup_doc}, -#endif -#ifdef HAVE_SOCKETPAIR - {"socketpair", socket_socketpair, - METH_VARARGS, socketpair_doc}, + _SOCKET_DUP_METHODDEF #endif + _SOCKET_SOCKETPAIR_METHODDEF _SOCKET_NTOHS_METHODDEF _SOCKET_NTOHL_METHODDEF _SOCKET_HTONS_METHODDEF _SOCKET_HTONL_METHODDEF _SOCKET_INET_ATON_METHODDEF -#ifdef HAVE_INET_NTOA _SOCKET_INET_NTOA_METHODDEF -#endif -#ifdef HAVE_INET_PTON - {"inet_pton", socket_inet_pton, - METH_VARARGS, inet_pton_doc}, - {"inet_ntop", socket_inet_ntop, - METH_VARARGS, inet_ntop_doc}, -#endif -#ifdef HAVE_GETADDRINFO - {"getaddrinfo", _PyCFunction_CAST(socket_getaddrinfo), - METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc}, -#endif -#ifdef HAVE_GETNAMEINFO - {"getnameinfo", socket_getnameinfo, - METH_VARARGS, getnameinfo_doc}, -#endif - {"getdefaulttimeout", socket_getdefaulttimeout, - METH_NOARGS, getdefaulttimeout_doc}, - {"setdefaulttimeout", socket_setdefaulttimeout, - METH_O, setdefaulttimeout_doc}, + _SOCKET_INET_PTON_METHODDEF + _SOCKET_INET_NTOP_METHODDEF + _SOCKET_GETADDRINFO_METHODDEF + _SOCKET_GETNAMEINFO_METHODDEF + _SOCKET_GETDEFAULTTIMEOUT_METHODDEF + _SOCKET_SETDEFAULTTIMEOUT_METHODDEF #if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) - {"if_nameindex", socket_if_nameindex, - METH_NOARGS, if_nameindex_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}, -#ifdef CMSG_SPACE - {"CMSG_SPACE", socket_CMSG_SPACE, - METH_VARARGS, CMSG_SPACE_doc}, -#endif -#endif + _SOCKET_CMSG_LEN_METHODDEF + _SOCKET_CMSG_SPACE_METHODDEF {NULL, NULL} /* Sentinel */ };