summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/socket.rst8
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/socketmodule.c107
-rw-r--r--Modules/socketmodule.h10
-rwxr-xr-xconfigure6
-rw-r--r--configure.in6
-rw-r--r--pyconfig.h.in6
8 files changed, 141 insertions, 6 deletions
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index cb2ab23..6b7728f 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -99,6 +99,14 @@ created. Socket addresses are represented as follows:
``'can0'``. The network interface name ``''`` can be used to receive packets
from all network interfaces of this family.
+- A string or a tuple ``(id, unit)`` is used for the :const:`SYSPROTO_CONTROL`
+ protocol of the :const:`PF_SYSTEM` family. The string is the name of a
+ kernel control using a dynamically-assigned ID. The tuple can be used if ID
+ and unit number of the kernel control are known or if a registered ID is
+ used.
+
+ .. versionadded:: 3.3
+
- Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`)
support specific representations.
diff --git a/Misc/ACKS b/Misc/ACKS
index aafb51f..9f66255 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -366,6 +366,7 @@ Jonathan Giddy
Johannes Gijsbers
Michael Gilfix
Yannick Gingras
+Michael Goderbauer
Christoph Gohlke
Tim Golden
Tiago Gonçalves
diff --git a/Misc/NEWS b/Misc/NEWS
index 68998e3..72a943d 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
Core and Builtins
-----------------
+- Issue #13777: Add PF_SYSTEM sockets on OS X.
+ Patch by Michael Goderbauer.
+
- Issue #13908: Ready types returned from PyType_FromSpec.
- Issue #11235: Fix OverflowError when trying to import a source file whose
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,
diff --git a/configure b/configure
index ebae8f5..5ddb7046 100755
--- a/configure
+++ b/configure
@@ -6144,10 +6144,10 @@ ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
sched.h shadow.h signal.h stdint.h stropts.h termios.h \
unistd.h utime.h \
poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
-sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \
-sys/lock.h sys/mkdev.h sys/modem.h \
+sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h \
+sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
-sys/stat.h sys/syscall.h sys/termio.h sys/time.h \
+sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h spawn.h util.h
diff --git a/configure.in b/configure.in
index f0beb6b..ed7f0ad 100644
--- a/configure.in
+++ b/configure.in
@@ -1334,10 +1334,10 @@ ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
sched.h shadow.h signal.h stdint.h stropts.h termios.h \
unistd.h utime.h \
poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
-sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \
-sys/lock.h sys/mkdev.h sys/modem.h \
+sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h \
+sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
-sys/stat.h sys/syscall.h sys/termio.h sys/time.h \
+sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h spawn.h util.h)
diff --git a/pyconfig.h.in b/pyconfig.h.in
index fd4cfc7..5dd9878 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -908,6 +908,9 @@
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
+/* Define to 1 if you have the <sys/kern_control.h> header file. */
+#undef HAVE_SYS_KERN_CONTROL_H
+
/* Define to 1 if you have the <sys/loadavg.h> header file. */
#undef HAVE_SYS_LOADAVG_H
@@ -951,6 +954,9 @@
/* Define to 1 if you have the <sys/syscall.h> header file. */
#undef HAVE_SYS_SYSCALL_H
+/* Define to 1 if you have the <sys/sys_domain.h> header file. */
+#undef HAVE_SYS_SYS_DOMAIN_H
+
/* Define to 1 if you have the <sys/termio.h> header file. */
#undef HAVE_SYS_TERMIO_H