Issue #13777: Add PF_SYSTEM sockets on OS X.
Patch by Michael Goderbauer.
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 @@
# 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);