--- /dev/null
+/* Socket module header file */\r
+\r
+/* Includes needed for the sockaddr_* symbols below */\r
+#ifndef MS_WINDOWS\r
+#ifdef __VMS\r
+# include <socket.h>\r
+# else\r
+# include <sys/socket.h>\r
+# endif\r
+# include <netinet/in.h>\r
+# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))\r
+# include <netinet/tcp.h>\r
+# endif\r
+\r
+#else /* MS_WINDOWS */\r
+# include <winsock2.h>\r
+# include <ws2tcpip.h>\r
+/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h\r
+ * Separate SDKs have all the functions we want, but older ones don't have\r
+ * any version information.\r
+ * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.\r
+ */\r
+# ifdef SIO_GET_MULTICAST_FILTER\r
+# include <MSTcpIP.h> /* for SIO_RCVALL */\r
+# define HAVE_ADDRINFO\r
+# define HAVE_SOCKADDR_STORAGE\r
+# define HAVE_GETADDRINFO\r
+# define HAVE_GETNAMEINFO\r
+# define ENABLE_IPV6\r
+# else\r
+typedef int socklen_t;\r
+# endif /* IPPROTO_IPV6 */\r
+#endif /* MS_WINDOWS */\r
+\r
+#ifdef HAVE_SYS_UN_H\r
+# include <sys/un.h>\r
+#else\r
+# undef AF_UNIX\r
+#endif\r
+\r
+#ifdef HAVE_LINUX_NETLINK_H\r
+# ifdef HAVE_ASM_TYPES_H\r
+# include <asm/types.h>\r
+# endif\r
+# include <linux/netlink.h>\r
+#else\r
+# undef AF_NETLINK\r
+#endif\r
+\r
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H\r
+#include <bluetooth/bluetooth.h>\r
+#include <bluetooth/rfcomm.h>\r
+#include <bluetooth/l2cap.h>\r
+#include <bluetooth/sco.h>\r
+#include <bluetooth/hci.h>\r
+#endif\r
+\r
+#ifdef HAVE_BLUETOOTH_H\r
+#include <bluetooth.h>\r
+#endif\r
+\r
+#ifdef HAVE_NETPACKET_PACKET_H\r
+# include <sys/ioctl.h>\r
+# include <net/if.h>\r
+# include <netpacket/packet.h>\r
+#endif\r
+\r
+#ifdef HAVE_LINUX_TIPC_H\r
+# include <linux/tipc.h>\r
+#endif\r
+\r
+#ifndef Py__SOCKET_H\r
+#define Py__SOCKET_H\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* Python module and C API name */\r
+#define PySocket_MODULE_NAME "_socket"\r
+#define PySocket_CAPI_NAME "CAPI"\r
+#define PySocket_CAPSULE_NAME (PySocket_MODULE_NAME "." PySocket_CAPI_NAME)\r
+\r
+/* Abstract the socket file descriptor type */\r
+#ifdef MS_WINDOWS\r
+typedef SOCKET SOCKET_T;\r
+# ifdef MS_WIN64\r
+# define SIZEOF_SOCKET_T 8\r
+# else\r
+# define SIZEOF_SOCKET_T 4\r
+# endif\r
+#else\r
+typedef int SOCKET_T;\r
+# define SIZEOF_SOCKET_T SIZEOF_INT\r
+#endif\r
+\r
+/* Socket address */\r
+typedef union sock_addr {\r
+ struct sockaddr_in in;\r
+#ifdef AF_UNIX\r
+ struct sockaddr_un un;\r
+#endif\r
+#ifdef AF_NETLINK\r
+ struct sockaddr_nl nl;\r
+#endif\r
+#ifdef ENABLE_IPV6\r
+ struct sockaddr_in6 in6;\r
+ struct sockaddr_storage storage;\r
+#endif\r
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H\r
+ struct sockaddr_l2 bt_l2;\r
+ struct sockaddr_rc bt_rc;\r
+ struct sockaddr_sco bt_sco;\r
+ struct sockaddr_hci bt_hci;\r
+#endif\r
+#ifdef HAVE_NETPACKET_PACKET_H\r
+ struct sockaddr_ll ll;\r
+#endif\r
+} sock_addr_t;\r
+\r
+/* The object holding a socket. It holds some extra information,\r
+ like the address family, which is used to decode socket address\r
+ arguments properly. */\r
+\r
+typedef struct {\r
+ PyObject_HEAD\r
+ SOCKET_T sock_fd; /* Socket file descriptor */\r
+ int sock_family; /* Address family, e.g., AF_INET */\r
+ int sock_type; /* Socket type, e.g., SOCK_STREAM */\r
+ int sock_proto; /* Protocol type, usually 0 */\r
+ PyObject *(*errorhandler)(void); /* Error handler; checks\r
+ errno, returns NULL and\r
+ sets a Python exception */\r
+ double sock_timeout; /* Operation timeout in seconds;\r
+ 0.0 means non-blocking */\r
+ PyObject *weakreflist;\r
+} PySocketSockObject;\r
+\r
+/* --- C API ----------------------------------------------------*/\r
+\r
+/* Short explanation of what this C API export mechanism does\r
+ and how it works:\r
+\r
+ The _ssl module needs access to the type object defined in\r
+ the _socket module. Since cross-DLL linking introduces a lot of\r
+ problems on many platforms, the "trick" is to wrap the\r
+ C API of a module in a struct which then gets exported to\r
+ other modules via a PyCapsule.\r
+\r
+ The code in socketmodule.c defines this struct (which currently\r
+ only contains the type object reference, but could very\r
+ well also include other C APIs needed by other modules)\r
+ and exports it as PyCapsule via the module dictionary\r
+ under the name "CAPI".\r
+\r
+ Other modules can now include the socketmodule.h file\r
+ which defines the needed C APIs to import and set up\r
+ a static copy of this struct in the importing module.\r
+\r
+ After initialization, the importing module can then\r
+ access the C APIs from the _socket module by simply\r
+ referring to the static struct, e.g.\r
+\r
+ Load _socket module and its C API; this sets up the global\r
+ PySocketModule:\r
+\r
+ if (PySocketModule_ImportModuleAndAPI())\r
+ return;\r
+\r
+\r
+ Now use the C API as if it were defined in the using\r
+ module:\r
+\r
+ if (!PyArg_ParseTuple(args, "O!|zz:ssl",\r
+\r
+ PySocketModule.Sock_Type,\r
+\r
+ (PyObject*)&Sock,\r
+ &key_file, &cert_file))\r
+ return NULL;\r
+\r
+ Support could easily be extended to export more C APIs/symbols\r
+ this way. Currently, only the type object is exported,\r
+ other candidates would be socket constructors and socket\r
+ access functions.\r
+\r
+*/\r
+\r
+/* C API for usage by other Python modules */\r
+typedef struct {\r
+ PyTypeObject *Sock_Type;\r
+ PyObject *error;\r
+} PySocketModule_APIObject;\r
+\r
+/* XXX The net effect of the following appears to be to define a function\r
+ XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't\r
+ XXX defined there directly.\r
+\r
+ >>> It's defined here because other modules might also want to use\r
+ >>> the C API.\r
+\r
+*/\r
+#ifndef PySocket_BUILDING_SOCKET\r
+\r
+/* --- C API ----------------------------------------------------*/\r
+\r
+/* Interfacestructure to C API for other modules.\r
+ Call PySocketModule_ImportModuleAndAPI() to initialize this\r
+ structure. After that usage is simple:\r
+\r
+ if (!PyArg_ParseTuple(args, "O!|zz:ssl",\r
+ &PySocketModule.Sock_Type, (PyObject*)&Sock,\r
+ &key_file, &cert_file))\r
+ return NULL;\r
+ ...\r
+*/\r
+\r
+static\r
+PySocketModule_APIObject PySocketModule;\r
+\r
+/* You *must* call this before using any of the functions in\r
+ PySocketModule and check its outcome; otherwise all accesses will\r
+ result in a segfault. Returns 0 on success. */\r
+\r
+#ifndef DPRINTF\r
+# define DPRINTF if (0) printf\r
+#endif\r
+\r
+static\r
+int PySocketModule_ImportModuleAndAPI(void)\r
+{\r
+ void *api;\r
+\r
+ DPRINTF(" Loading capsule %s\n", PySocket_CAPSULE_NAME);\r
+ api = PyCapsule_Import(PySocket_CAPSULE_NAME, 1);\r
+ if (api == NULL)\r
+ goto onError;\r
+ memcpy(&PySocketModule, api, sizeof(PySocketModule));\r
+ DPRINTF(" API object loaded and initialized.\n");\r
+ return 0;\r
+\r
+ onError:\r
+ DPRINTF(" not found.\n");\r
+ return -1;\r
+}\r
+\r
+#endif /* !PySocket_BUILDING_SOCKET */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* !Py__SOCKET_H */\r