source: python/trunk/Modules/socketmodule.h@ 1538

Last change on this file since 1538 was 1538, checked in by Silvan Scherrer, 7 years ago

adjust getaddrinfo and friends to latest libcx

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