[Python-checkins] cpython: Issue #13777: Add PF_SYSTEM sockets on OS X.

martin.v.loewis python-checkins at python.org
Fri Feb 3 17:45:07 CET 2012


http://hg.python.org/cpython/rev/aa3680d2c24d
changeset:   74741:aa3680d2c24d
user:        Martin v. Löwis <martin at v.loewis.de>
date:        Fri Feb 03 17:44:58 2012 +0100
summary:
  Issue #13777: Add PF_SYSTEM sockets on OS X.
Patch by Michael Goderbauer.

files:
  Doc/library/socket.rst |    8 ++
  Misc/ACKS              |    1 +
  Misc/NEWS              |    3 +
  Modules/socketmodule.c |  107 +++++++++++++++++++++++++++++
  Modules/socketmodule.h |   10 ++
  configure              |    6 +-
  configure.in           |    6 +-
  pyconfig.h.in          |    6 +
  8 files changed, 141 insertions(+), 6 deletions(-)


diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -99,6 +99,14 @@
   ``'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
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -366,6 +366,7 @@
 Johannes Gijsbers
 Michael Gilfix
 Yannick Gingras
+Michael Goderbauer
 Christoph Gohlke
 Tim Golden
 Tiago Gonçalves
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 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
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -218,6 +218,11 @@
 #  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 @@
     }
 #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 @@
             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 @@
         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 @@
     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 @@
     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
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -80,6 +80,13 @@
 #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 @@
 #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
--- a/configure
+++ b/configure
@@ -6144,10 +6144,10 @@
 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
--- a/configure.in
+++ b/configure.in
@@ -1334,10 +1334,10 @@
 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
--- 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
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list