/Modules/socketmodule.h

http://unladen-swallow.googlecode.com/ · C Header · 264 lines · 149 code · 28 blank · 87 comment · 11 complexity · 84b36326160876b69b525dbebe5108bc MD5 · raw file

  1. /* Socket module header file */
  2. /* Includes needed for the sockaddr_* symbols below */
  3. #ifndef MS_WINDOWS
  4. #ifdef __VMS
  5. # include <socket.h>
  6. # else
  7. # include <sys/socket.h>
  8. # endif
  9. # include <netinet/in.h>
  10. # if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
  11. # include <netinet/tcp.h>
  12. # endif
  13. #else /* MS_WINDOWS */
  14. # include <winsock2.h>
  15. # include <ws2tcpip.h>
  16. /* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
  17. * Separate SDKs have all the functions we want, but older ones don't have
  18. * any version information.
  19. * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
  20. */
  21. # ifdef SIO_GET_MULTICAST_FILTER
  22. # include <MSTcpIP.h> /* for SIO_RCVALL */
  23. # define HAVE_ADDRINFO
  24. # define HAVE_SOCKADDR_STORAGE
  25. # define HAVE_GETADDRINFO
  26. # define HAVE_GETNAMEINFO
  27. # define ENABLE_IPV6
  28. # else
  29. typedef int socklen_t;
  30. # endif /* IPPROTO_IPV6 */
  31. #endif /* MS_WINDOWS */
  32. #ifdef HAVE_SYS_UN_H
  33. # include <sys/un.h>
  34. #else
  35. # undef AF_UNIX
  36. #endif
  37. #ifdef HAVE_LINUX_NETLINK_H
  38. # ifdef HAVE_ASM_TYPES_H
  39. # include <asm/types.h>
  40. # endif
  41. # include <linux/netlink.h>
  42. #else
  43. # undef AF_NETLINK
  44. #endif
  45. #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
  46. #include <bluetooth/bluetooth.h>
  47. #include <bluetooth/rfcomm.h>
  48. #include <bluetooth/l2cap.h>
  49. #include <bluetooth/sco.h>
  50. #include <bluetooth/hci.h>
  51. #endif
  52. #ifdef HAVE_BLUETOOTH_H
  53. #include <bluetooth.h>
  54. #endif
  55. #ifdef HAVE_NETPACKET_PACKET_H
  56. # include <sys/ioctl.h>
  57. # include <net/if.h>
  58. # include <netpacket/packet.h>
  59. #endif
  60. #ifdef HAVE_LINUX_TIPC_H
  61. # include <linux/tipc.h>
  62. #endif
  63. #ifndef Py__SOCKET_H
  64. #define Py__SOCKET_H
  65. #ifdef __cplusplus
  66. extern "C" {
  67. #endif
  68. /* Python module and C API name */
  69. #define PySocket_MODULE_NAME "_socket"
  70. #define PySocket_CAPI_NAME "CAPI"
  71. /* Abstract the socket file descriptor type */
  72. #ifdef MS_WINDOWS
  73. typedef SOCKET SOCKET_T;
  74. # ifdef MS_WIN64
  75. # define SIZEOF_SOCKET_T 8
  76. # else
  77. # define SIZEOF_SOCKET_T 4
  78. # endif
  79. #else
  80. typedef int SOCKET_T;
  81. # define SIZEOF_SOCKET_T SIZEOF_INT
  82. #endif
  83. /* Socket address */
  84. typedef union sock_addr {
  85. struct sockaddr_in in;
  86. #ifdef AF_UNIX
  87. struct sockaddr_un un;
  88. #endif
  89. #ifdef AF_NETLINK
  90. struct sockaddr_nl nl;
  91. #endif
  92. #ifdef ENABLE_IPV6
  93. struct sockaddr_in6 in6;
  94. struct sockaddr_storage storage;
  95. #endif
  96. #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
  97. struct sockaddr_l2 bt_l2;
  98. struct sockaddr_rc bt_rc;
  99. struct sockaddr_sco bt_sco;
  100. struct sockaddr_hci bt_hci;
  101. #endif
  102. #ifdef HAVE_NETPACKET_PACKET_H
  103. struct sockaddr_ll ll;
  104. #endif
  105. } sock_addr_t;
  106. /* The object holding a socket. It holds some extra information,
  107. like the address family, which is used to decode socket address
  108. arguments properly. */
  109. typedef struct {
  110. PyObject_HEAD
  111. SOCKET_T sock_fd; /* Socket file descriptor */
  112. int sock_family; /* Address family, e.g., AF_INET */
  113. int sock_type; /* Socket type, e.g., SOCK_STREAM */
  114. int sock_proto; /* Protocol type, usually 0 */
  115. PyObject *(*errorhandler)(void); /* Error handler; checks
  116. errno, returns NULL and
  117. sets a Python exception */
  118. double sock_timeout; /* Operation timeout in seconds;
  119. 0.0 means non-blocking */
  120. } PySocketSockObject;
  121. /* --- C API ----------------------------------------------------*/
  122. /* Short explanation of what this C API export mechanism does
  123. and how it works:
  124. The _ssl module needs access to the type object defined in
  125. the _socket module. Since cross-DLL linking introduces a lot of
  126. problems on many platforms, the "trick" is to wrap the
  127. C API of a module in a struct which then gets exported to
  128. other modules via a PyCObject.
  129. The code in socketmodule.c defines this struct (which currently
  130. only contains the type object reference, but could very
  131. well also include other C APIs needed by other modules)
  132. and exports it as PyCObject via the module dictionary
  133. under the name "CAPI".
  134. Other modules can now include the socketmodule.h file
  135. which defines the needed C APIs to import and set up
  136. a static copy of this struct in the importing module.
  137. After initialization, the importing module can then
  138. access the C APIs from the _socket module by simply
  139. referring to the static struct, e.g.
  140. Load _socket module and its C API; this sets up the global
  141. PySocketModule:
  142. if (PySocketModule_ImportModuleAndAPI())
  143. return;
  144. Now use the C API as if it were defined in the using
  145. module:
  146. if (!PyArg_ParseTuple(args, "O!|zz:ssl",
  147. PySocketModule.Sock_Type,
  148. (PyObject*)&Sock,
  149. &key_file, &cert_file))
  150. return NULL;
  151. Support could easily be extended to export more C APIs/symbols
  152. this way. Currently, only the type object is exported,
  153. other candidates would be socket constructors and socket
  154. access functions.
  155. */
  156. /* C API for usage by other Python modules */
  157. typedef struct {
  158. PyTypeObject *Sock_Type;
  159. PyObject *error;
  160. } PySocketModule_APIObject;
  161. /* XXX The net effect of the following appears to be to define a function
  162. XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
  163. XXX defined there directly.
  164. >>> It's defined here because other modules might also want to use
  165. >>> the C API.
  166. */
  167. #ifndef PySocket_BUILDING_SOCKET
  168. /* --- C API ----------------------------------------------------*/
  169. /* Interfacestructure to C API for other modules.
  170. Call PySocketModule_ImportModuleAndAPI() to initialize this
  171. structure. After that usage is simple:
  172. if (!PyArg_ParseTuple(args, "O!|zz:ssl",
  173. &PySocketModule.Sock_Type, (PyObject*)&Sock,
  174. &key_file, &cert_file))
  175. return NULL;
  176. ...
  177. */
  178. static
  179. PySocketModule_APIObject PySocketModule;
  180. /* You *must* call this before using any of the functions in
  181. PySocketModule and check its outcome; otherwise all accesses will
  182. result in a segfault. Returns 0 on success. */
  183. #ifndef DPRINTF
  184. # define DPRINTF if (0) printf
  185. #endif
  186. static
  187. int PySocketModule_ImportModuleAndAPI(void)
  188. {
  189. PyObject *mod = 0, *v = 0;
  190. char *apimodule = PySocket_MODULE_NAME;
  191. char *apiname = PySocket_CAPI_NAME;
  192. void *api;
  193. DPRINTF("Importing the %s C API...\n", apimodule);
  194. mod = PyImport_ImportModuleNoBlock(apimodule);
  195. if (mod == NULL)
  196. goto onError;
  197. DPRINTF(" %s package found\n", apimodule);
  198. v = PyObject_GetAttrString(mod, apiname);
  199. if (v == NULL)
  200. goto onError;
  201. Py_DECREF(mod);
  202. DPRINTF(" API object %s found\n", apiname);
  203. api = PyCObject_AsVoidPtr(v);
  204. if (api == NULL)
  205. goto onError;
  206. Py_DECREF(v);
  207. memcpy(&PySocketModule, api, sizeof(PySocketModule));
  208. DPRINTF(" API object loaded and initialized.\n");
  209. return 0;
  210. onError:
  211. DPRINTF(" not found.\n");
  212. Py_XDECREF(mod);
  213. Py_XDECREF(v);
  214. return -1;
  215. }
  216. #endif /* !PySocket_BUILDING_SOCKET */
  217. #ifdef __cplusplus
  218. }
  219. #endif
  220. #endif /* !Py__SOCKET_H */