diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2012-02-03 16:44:58 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2012-02-03 16:44:58 (GMT) |
commit | 9d6c66933a30d938bd883039b778266123500adf (patch) | |
tree | be03b235a350d59048f8fb73db560ad7805001f6 /Modules | |
parent | 61c4e10035aa1ffe5c0d78e5b918b8df4e20a263 (diff) | |
download | cpython-9d6c66933a30d938bd883039b778266123500adf.zip cpython-9d6c66933a30d938bd883039b778266123500adf.tar.gz cpython-9d6c66933a30d938bd883039b778266123500adf.tar.bz2 |
Issue #13777: Add PF_SYSTEM sockets on OS X.
Patch by Michael Goderbauer.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/socketmodule.c | 107 | ||||
-rw-r--r-- | Modules/socketmodule.h | 10 |
2 files changed, 117 insertions, 0 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index b2ab5e9..d0b89c6 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -218,6 +218,11 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include <ioctl.h> #endif +#ifdef __APPLE__ +# include <sys/ioctl.h> +#endif + + #if defined(PYOS_OS2) # define INCL_DOS # define INCL_DOSERRORS @@ -1239,6 +1244,23 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch(proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + { + struct sockaddr_ctl *a = (struct sockaddr_ctl *)addr; + return Py_BuildValue("(II)", a->sc_id, a->sc_unit); + } +#endif + default: + PyErr_SetString(PyExc_ValueError, + "Invalid address type"); + return 0; + } +#endif + /* More cases here... */ default: @@ -1677,6 +1699,64 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } #endif + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch (s->sock_proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + { + struct sockaddr_ctl *addr; + + addr = (struct sockaddr_ctl *)addr_ret; + addr->sc_family = AF_SYSTEM; + addr->ss_sysaddr = AF_SYS_CONTROL; + + if (PyUnicode_Check(args)) { + struct ctl_info info; + PyObject *ctl_name; + + if (!PyArg_Parse(args, "O&", + PyUnicode_FSConverter, &ctl_name)) { + return 0; + } + + if (PyBytes_GET_SIZE(ctl_name) > sizeof(info.ctl_name)) { + PyErr_SetString(PyExc_ValueError, + "provided string is too long"); + Py_DECREF(ctl_name); + return 0; + } + strncpy(info.ctl_name, PyBytes_AS_STRING(ctl_name), + sizeof(info.ctl_name)); + Py_DECREF(ctl_name); + + if (ioctl(s->sock_fd, CTLIOCGINFO, &info)) { + PyErr_SetString(PyExc_OSError, + "cannot find kernel control with provided name"); + return 0; + } + + addr->sc_id = info.ctl_id; + addr->sc_unit = 0; + } else if (!PyArg_ParseTuple(args, "II", + &(addr->sc_id), &(addr->sc_unit))) { + PyErr_SetString(PyExc_TypeError, "getsockaddrarg: " + "expected str or tuple of two ints"); + + return 0; + } + + *len_ret = sizeof(*addr); + return 1; + } +#endif + default: + PyErr_SetString(PyExc_OSError, + "getsockaddrarg: unsupported PF_SYSTEM protocol"); + return 0; + } +#endif /* More cases here... */ @@ -1783,6 +1863,21 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) return 1; } #endif + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch(s->sock_proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + *len_ret = sizeof (struct sockaddr_ctl); + return 1; +#endif + default: + PyErr_SetString(PyExc_OSError, "getsockaddrlen: " + "unknown PF_SYSTEM protocol"); + return 0; + } +#endif /* More cases here... */ @@ -5660,6 +5755,14 @@ PyInit__socket(void) PyModule_AddIntConstant(m, "PF_RDS", PF_RDS); #endif +/* Kernel event messages */ +#ifdef PF_SYSTEM + PyModule_AddIntConstant(m, "PF_SYSTEM", PF_SYSTEM); +#endif +#ifdef AF_SYSTEM + PyModule_AddIntConstant(m, "AF_SYSTEM", AF_SYSTEM); +#endif + #ifdef AF_PACKET PyModule_AddIntMacro(m, AF_PACKET); #endif @@ -6096,6 +6199,10 @@ PyInit__socket(void) PyModule_AddIntConstant(m, "IPPROTO_MAX", IPPROTO_MAX); #endif +#ifdef SYSPROTO_CONTROL + PyModule_AddIntConstant(m, "SYSPROTO_CONTROL", SYSPROTO_CONTROL); +#endif + /* Some port configuration */ #ifdef IPPORT_RESERVED PyModule_AddIntConstant(m, "IPPORT_RESERVED", IPPORT_RESERVED); diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 59d4cb1..0435878 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -80,6 +80,13 @@ typedef int socklen_t; #include <linux/can/raw.h> #endif +#ifdef HAVE_SYS_SYS_DOMAIN_H +#include <sys/sys_domain.h> +#endif +#ifdef HAVE_SYS_KERN_CONTROL_H +#include <sys/kern_control.h> +#endif + #ifndef Py__SOCKET_H #define Py__SOCKET_H #ifdef __cplusplus @@ -138,6 +145,9 @@ typedef union sock_addr { #ifdef HAVE_LINUX_CAN_H struct sockaddr_can can; #endif +#ifdef HAVE_SYS_KERN_CONTROL_H + struct sockaddr_ctl ctl; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information, |