Tagging 3.0a4.
[python/dscho.git] / Modules / socketmodule.h
blob114084cea7d9e613e8c236edc8812bacd33fe5d2
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(__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 # include <MSTcpIP.h> /* for SIO_RCVALL */
20 # define HAVE_ADDRINFO
21 # define HAVE_SOCKADDR_STORAGE
22 # define HAVE_GETADDRINFO
23 # define HAVE_GETNAMEINFO
24 # define ENABLE_IPV6
25 #else
26 # define WIN32_LEAN_AND_MEAN
27 # include <winsock.h>
28 #endif
29 #endif
31 #ifdef HAVE_SYS_UN_H
32 # include <sys/un.h>
33 #else
34 # undef AF_UNIX
35 #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
46 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
47 #include <bluetooth/bluetooth.h>
48 #include <bluetooth/rfcomm.h>
49 #include <bluetooth/l2cap.h>
50 #include <bluetooth/sco.h>
51 #include <bluetooth/hci.h>
52 #endif
54 #ifdef HAVE_BLUETOOTH_H
55 #include <bluetooth.h>
56 #endif
58 #ifdef HAVE_NETPACKET_PACKET_H
59 # include <sys/ioctl.h>
60 # include <net/if.h>
61 # include <netpacket/packet.h>
62 #endif
64 #ifdef HAVE_LINUX_TIPC_H
65 # include <linux/tipc.h>
66 #endif
68 #ifndef Py__SOCKET_H
69 #define Py__SOCKET_H
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
74 /* Python module and C API name */
75 #define PySocket_MODULE_NAME "_socket"
76 #define PySocket_CAPI_NAME "CAPI"
78 /* Abstract the socket file descriptor type */
79 #ifdef MS_WINDOWS
80 typedef SOCKET SOCKET_T;
81 # ifdef MS_WIN64
82 # define SIZEOF_SOCKET_T 8
83 # else
84 # define SIZEOF_SOCKET_T 4
85 # endif
86 #else
87 typedef int SOCKET_T;
88 # define SIZEOF_SOCKET_T SIZEOF_INT
89 #endif
91 /* Socket address */
92 typedef union sock_addr {
93 struct sockaddr_in in;
94 #ifdef AF_UNIX
95 struct sockaddr_un un;
96 #endif
97 #ifdef AF_NETLINK
98 struct sockaddr_nl nl;
99 #endif
100 #ifdef ENABLE_IPV6
101 struct sockaddr_in6 in6;
102 struct sockaddr_storage storage;
103 #endif
104 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
105 struct sockaddr_l2 bt_l2;
106 struct sockaddr_rc bt_rc;
107 struct sockaddr_sco bt_sco;
108 struct sockaddr_hci bt_hci;
109 #endif
110 #ifdef HAVE_NETPACKET_PACKET_H
111 struct sockaddr_ll ll;
112 #endif
113 } sock_addr_t;
115 /* The object holding a socket. It holds some extra information,
116 like the address family, which is used to decode socket address
117 arguments properly. */
119 typedef struct {
120 PyObject_HEAD
121 SOCKET_T sock_fd; /* Socket file descriptor */
122 int sock_family; /* Address family, e.g., AF_INET */
123 int sock_type; /* Socket type, e.g., SOCK_STREAM */
124 int sock_proto; /* Protocol type, usually 0 */
125 PyObject *(*errorhandler)(void); /* Error handler; checks
126 errno, returns NULL and
127 sets a Python exception */
128 double sock_timeout; /* Operation timeout in seconds;
129 0.0 means non-blocking */
130 } PySocketSockObject;
132 /* --- C API ----------------------------------------------------*/
134 /* Short explanation of what this C API export mechanism does
135 and how it works:
137 The _ssl module needs access to the type object defined in
138 the _socket module. Since cross-DLL linking introduces a lot of
139 problems on many platforms, the "trick" is to wrap the
140 C API of a module in a struct which then gets exported to
141 other modules via a PyCObject.
143 The code in socketmodule.c defines this struct (which currently
144 only contains the type object reference, but could very
145 well also include other C APIs needed by other modules)
146 and exports it as PyCObject via the module dictionary
147 under the name "CAPI".
149 Other modules can now include the socketmodule.h file
150 which defines the needed C APIs to import and set up
151 a static copy of this struct in the importing module.
153 After initialization, the importing module can then
154 access the C APIs from the _socket module by simply
155 referring to the static struct, e.g.
157 Load _socket module and its C API; this sets up the global
158 PySocketModule:
160 if (PySocketModule_ImportModuleAndAPI())
161 return;
164 Now use the C API as if it were defined in the using
165 module:
167 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
169 PySocketModule.Sock_Type,
171 (PyObject*)&Sock,
172 &key_file, &cert_file))
173 return NULL;
175 Support could easily be extended to export more C APIs/symbols
176 this way. Currently, only the type object is exported,
177 other candidates would be socket constructors and socket
178 access functions.
182 /* C API for usage by other Python modules */
183 typedef struct {
184 PyTypeObject *Sock_Type;
185 PyObject *error;
186 } PySocketModule_APIObject;
188 /* XXX The net effect of the following appears to be to define a function
189 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
190 XXX defined there directly.
192 >>> It's defined here because other modules might also want to use
193 >>> the C API.
196 #ifndef PySocket_BUILDING_SOCKET
198 /* --- C API ----------------------------------------------------*/
200 /* Interfacestructure to C API for other modules.
201 Call PySocketModule_ImportModuleAndAPI() to initialize this
202 structure. After that usage is simple:
204 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
205 &PySocketModule.Sock_Type, (PyObject*)&Sock,
206 &key_file, &cert_file))
207 return NULL;
211 static
212 PySocketModule_APIObject PySocketModule;
214 /* You *must* call this before using any of the functions in
215 PySocketModule and check its outcome; otherwise all accesses will
216 result in a segfault. Returns 0 on success. */
218 #ifndef DPRINTF
219 # define DPRINTF if (0) printf
220 #endif
222 static
223 int PySocketModule_ImportModuleAndAPI(void)
225 PyObject *mod = 0, *v = 0;
226 char *apimodule = PySocket_MODULE_NAME;
227 char *apiname = PySocket_CAPI_NAME;
228 void *api;
230 DPRINTF("Importing the %s C API...\n", apimodule);
231 mod = PyImport_ImportModuleNoBlock(apimodule);
232 if (mod == NULL)
233 goto onError;
234 DPRINTF(" %s package found\n", apimodule);
235 v = PyObject_GetAttrString(mod, apiname);
236 if (v == NULL)
237 goto onError;
238 Py_DECREF(mod);
239 DPRINTF(" API object %s found\n", apiname);
240 api = PyCObject_AsVoidPtr(v);
241 if (api == NULL)
242 goto onError;
243 Py_DECREF(v);
244 memcpy(&PySocketModule, api, sizeof(PySocketModule));
245 DPRINTF(" API object loaded and initialized.\n");
246 return 0;
248 onError:
249 DPRINTF(" not found.\n");
250 Py_XDECREF(mod);
251 Py_XDECREF(v);
252 return -1;
255 #endif /* !PySocket_BUILDING_SOCKET */
257 #ifdef __cplusplus
259 #endif
260 #endif /* !Py__SOCKET_H */