Minor edits
[pytest.git] / Modules / socketmodule.h
blobae38c86cbc698a344e3aa0a0010c94972b54d2d6
1 /* Socket module header file */
3 /* Includes needed for the sockaddr_* symbols below */
4 #ifndef MS_WINDOWS
5 #ifdef __VMS
6 # include <socket.h>
7 # else
8 # include <sys/socket.h>
9 # endif
10 # include <netinet/in.h>
11 # if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
12 # include <netinet/tcp.h>
13 # endif
15 #else /* MS_WINDOWS */
16 #if _MSC_VER >= 1300
17 # include <winsock2.h>
18 # include <ws2tcpip.h>
19 # define HAVE_ADDRINFO
20 # define HAVE_SOCKADDR_STORAGE
21 # define HAVE_GETADDRINFO
22 # define HAVE_GETNAMEINFO
23 # define ENABLE_IPV6
24 #else
25 # include <winsock.h>
26 #endif
27 #endif
29 #ifdef HAVE_SYS_UN_H
30 # include <sys/un.h>
31 #else
32 # undef AF_UNIX
33 #endif
35 #ifdef HAVE_LINUX_NETLINK_H
36 # ifdef HAVE_ASM_TYPES_H
37 # include <asm/types.h>
38 # endif
39 # include <linux/netlink.h>
40 #else
41 # undef AF_NETLINK
42 #endif
44 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
45 #include <bluetooth/bluetooth.h>
46 #include <bluetooth/rfcomm.h>
47 #include <bluetooth/l2cap.h>
48 #include <bluetooth/sco.h>
49 #endif
51 #ifdef HAVE_BLUETOOTH_H
52 #include <bluetooth.h>
53 #endif
55 #ifdef HAVE_NETPACKET_PACKET_H
56 # include <sys/ioctl.h>
57 # include <net/if.h>
58 # include <netpacket/packet.h>
59 #endif
61 #ifndef Py__SOCKET_H
62 #define Py__SOCKET_H
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
67 /* Python module and C API name */
68 #define PySocket_MODULE_NAME "_socket"
69 #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
84 /* Socket address */
85 typedef union sock_addr {
86 struct sockaddr_in in;
87 #ifdef AF_UNIX
88 struct sockaddr_un un;
89 #endif
90 #ifdef AF_NETLINK
91 struct sockaddr_nl nl;
92 #endif
93 #ifdef ENABLE_IPV6
94 struct sockaddr_in6 in6;
95 struct sockaddr_storage storage;
96 #endif
97 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
98 struct sockaddr_l2 bt_l2;
99 struct sockaddr_rc bt_rc;
100 struct sockaddr_sco bt_sco;
101 #endif
102 #ifdef HAVE_NETPACKET_PACKET_H
103 struct sockaddr_ll ll;
104 #endif
105 } sock_addr_t;
107 /* The object holding a socket. It holds some extra information,
108 like the address family, which is used to decode socket address
109 arguments properly. */
111 typedef struct {
112 PyObject_HEAD
113 SOCKET_T sock_fd; /* Socket file descriptor */
114 int sock_family; /* Address family, e.g., AF_INET */
115 int sock_type; /* Socket type, e.g., SOCK_STREAM */
116 int sock_proto; /* Protocol type, usually 0 */
117 sock_addr_t sock_addr; /* Socket address */
118 PyObject *(*errorhandler)(void); /* Error handler; checks
119 errno, returns NULL and
120 sets a Python exception */
121 double sock_timeout; /* Operation timeout in seconds;
122 0.0 means non-blocking */
123 } PySocketSockObject;
125 /* --- C API ----------------------------------------------------*/
127 /* Short explanation of what this C API export mechanism does
128 and how it works:
130 The _ssl module needs access to the type object defined in
131 the _socket module. Since cross-DLL linking introduces a lot of
132 problems on many platforms, the "trick" is to wrap the
133 C API of a module in a struct which then gets exported to
134 other modules via a PyCObject.
136 The code in socketmodule.c defines this struct (which currently
137 only contains the type object reference, but could very
138 well also include other C APIs needed by other modules)
139 and exports it as PyCObject via the module dictionary
140 under the name "CAPI".
142 Other modules can now include the socketmodule.h file
143 which defines the needed C APIs to import and set up
144 a static copy of this struct in the importing module.
146 After initialization, the importing module can then
147 access the C APIs from the _socket module by simply
148 referring to the static struct, e.g.
150 Load _socket module and its C API; this sets up the global
151 PySocketModule:
153 if (PySocketModule_ImportModuleAndAPI())
154 return;
157 Now use the C API as if it were defined in the using
158 module:
160 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
162 PySocketModule.Sock_Type,
164 (PyObject*)&Sock,
165 &key_file, &cert_file))
166 return NULL;
168 Support could easily be extended to export more C APIs/symbols
169 this way. Currently, only the type object is exported,
170 other candidates would be socket constructors and socket
171 access functions.
175 /* C API for usage by other Python modules */
176 typedef struct {
177 PyTypeObject *Sock_Type;
178 PyObject *error;
179 } PySocketModule_APIObject;
181 /* XXX The net effect of the following appears to be to define a function
182 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
183 XXX defined there directly.
185 >>> It's defined here because other modules might also want to use
186 >>> the C API.
189 #ifndef PySocket_BUILDING_SOCKET
191 /* --- C API ----------------------------------------------------*/
193 /* Interfacestructure to C API for other modules.
194 Call PySocketModule_ImportModuleAndAPI() to initialize this
195 structure. After that usage is simple:
197 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
198 &PySocketModule.Sock_Type, (PyObject*)&Sock,
199 &key_file, &cert_file))
200 return NULL;
204 static
205 PySocketModule_APIObject PySocketModule;
207 /* You *must* call this before using any of the functions in
208 PySocketModule and check its outcome; otherwise all accesses will
209 result in a segfault. Returns 0 on success. */
211 #ifndef DPRINTF
212 # define DPRINTF if (0) printf
213 #endif
215 static
216 int PySocketModule_ImportModuleAndAPI(void)
218 PyObject *mod = 0, *v = 0;
219 char *apimodule = PySocket_MODULE_NAME;
220 char *apiname = PySocket_CAPI_NAME;
221 void *api;
223 DPRINTF("Importing the %s C API...\n", apimodule);
224 mod = PyImport_ImportModule(apimodule);
225 if (mod == NULL)
226 goto onError;
227 DPRINTF(" %s package found\n", apimodule);
228 v = PyObject_GetAttrString(mod, apiname);
229 if (v == NULL)
230 goto onError;
231 Py_DECREF(mod);
232 DPRINTF(" API object %s found\n", apiname);
233 api = PyCObject_AsVoidPtr(v);
234 if (api == NULL)
235 goto onError;
236 Py_DECREF(v);
237 memcpy(&PySocketModule, api, sizeof(PySocketModule));
238 DPRINTF(" API object loaded and initialized.\n");
239 return 0;
241 onError:
242 DPRINTF(" not found.\n");
243 Py_XDECREF(mod);
244 Py_XDECREF(v);
245 return -1;
248 #endif /* !PySocket_BUILDING_SOCKET */
250 #ifdef __cplusplus
252 #endif
253 #endif /* !Py__SOCKET_H */