1
/* Socket module header file */
3
/* Includes needed for the sockaddr_* symbols below */
8
# include <sys/socket.h>
10
# include <netinet/in.h>
11
# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
12
# include <netinet/tcp.h>
15
#else /* MS_WINDOWS */
16
# include <winsock2.h>
17
# include <ws2tcpip.h>
18
/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
19
* Separate SDKs have all the functions we want, but older ones don't have
20
* any version information.
21
* I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
23
# ifdef SIO_GET_MULTICAST_FILTER
24
# include <MSTcpIP.h> /* for SIO_RCVALL */
25
# define HAVE_ADDRINFO
26
# define HAVE_SOCKADDR_STORAGE
27
# define HAVE_GETADDRINFO
28
# define HAVE_GETNAMEINFO
31
typedef int socklen_t;
32
# endif /* IPPROTO_IPV6 */
33
#endif /* MS_WINDOWS */
41
#ifdef HAVE_LINUX_NETLINK_H
42
# ifdef HAVE_ASM_TYPES_H
43
# include <asm/types.h>
45
# include <linux/netlink.h>
50
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
51
#include <bluetooth/bluetooth.h>
52
#include <bluetooth/rfcomm.h>
53
#include <bluetooth/l2cap.h>
54
#include <bluetooth/sco.h>
55
#include <bluetooth/hci.h>
58
#ifdef HAVE_BLUETOOTH_H
59
#include <bluetooth.h>
62
#ifdef HAVE_NETPACKET_PACKET_H
63
# include <sys/ioctl.h>
65
# include <netpacket/packet.h>
68
#ifdef HAVE_LINUX_TIPC_H
69
# include <linux/tipc.h>
78
/* Python module and C API name */
79
#define PySocket_MODULE_NAME "_socket"
80
#define PySocket_CAPI_NAME "CAPI"
82
/* Abstract the socket file descriptor type */
84
typedef SOCKET SOCKET_T;
86
# define SIZEOF_SOCKET_T 8
88
# define SIZEOF_SOCKET_T 4
92
# define SIZEOF_SOCKET_T SIZEOF_INT
96
typedef union sock_addr {
97
struct sockaddr_in in;
99
struct sockaddr_un un;
102
struct sockaddr_nl nl;
105
struct sockaddr_in6 in6;
106
struct sockaddr_storage storage;
108
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
109
struct sockaddr_l2 bt_l2;
110
struct sockaddr_rc bt_rc;
111
struct sockaddr_sco bt_sco;
112
struct sockaddr_hci bt_hci;
114
#ifdef HAVE_NETPACKET_PACKET_H
115
struct sockaddr_ll ll;
119
/* The object holding a socket. It holds some extra information,
120
like the address family, which is used to decode socket address
121
arguments properly. */
125
SOCKET_T sock_fd; /* Socket file descriptor */
126
int sock_family; /* Address family, e.g., AF_INET */
127
int sock_type; /* Socket type, e.g., SOCK_STREAM */
128
int sock_proto; /* Protocol type, usually 0 */
129
PyObject *(*errorhandler)(void); /* Error handler; checks
130
errno, returns NULL and
131
sets a Python exception */
132
double sock_timeout; /* Operation timeout in seconds;
133
0.0 means non-blocking */
134
} PySocketSockObject;
136
/* --- C API ----------------------------------------------------*/
138
/* Short explanation of what this C API export mechanism does
141
The _ssl module needs access to the type object defined in
142
the _socket module. Since cross-DLL linking introduces a lot of
143
problems on many platforms, the "trick" is to wrap the
144
C API of a module in a struct which then gets exported to
145
other modules via a PyCObject.
147
The code in socketmodule.c defines this struct (which currently
148
only contains the type object reference, but could very
149
well also include other C APIs needed by other modules)
150
and exports it as PyCObject via the module dictionary
151
under the name "CAPI".
153
Other modules can now include the socketmodule.h file
154
which defines the needed C APIs to import and set up
155
a static copy of this struct in the importing module.
157
After initialization, the importing module can then
158
access the C APIs from the _socket module by simply
159
referring to the static struct, e.g.
161
Load _socket module and its C API; this sets up the global
164
if (PySocketModule_ImportModuleAndAPI())
168
Now use the C API as if it were defined in the using
171
if (!PyArg_ParseTuple(args, "O!|zz:ssl",
173
PySocketModule.Sock_Type,
176
&key_file, &cert_file))
179
Support could easily be extended to export more C APIs/symbols
180
this way. Currently, only the type object is exported,
181
other candidates would be socket constructors and socket
186
/* C API for usage by other Python modules */
188
PyTypeObject *Sock_Type;
190
} PySocketModule_APIObject;
192
/* XXX The net effect of the following appears to be to define a function
193
XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
194
XXX defined there directly.
196
>>> It's defined here because other modules might also want to use
200
#ifndef PySocket_BUILDING_SOCKET
202
/* --- C API ----------------------------------------------------*/
204
/* Interfacestructure to C API for other modules.
205
Call PySocketModule_ImportModuleAndAPI() to initialize this
206
structure. After that usage is simple:
208
if (!PyArg_ParseTuple(args, "O!|zz:ssl",
209
&PySocketModule.Sock_Type, (PyObject*)&Sock,
210
&key_file, &cert_file))
216
PySocketModule_APIObject PySocketModule;
218
/* You *must* call this before using any of the functions in
219
PySocketModule and check its outcome; otherwise all accesses will
220
result in a segfault. Returns 0 on success. */
223
# define DPRINTF if (0) printf
227
int PySocketModule_ImportModuleAndAPI(void)
229
PyObject *mod = 0, *v = 0;
230
char *apimodule = PySocket_MODULE_NAME;
231
char *apiname = PySocket_CAPI_NAME;
234
DPRINTF("Importing the %s C API...\n", apimodule);
235
mod = PyImport_ImportModuleNoBlock(apimodule);
238
DPRINTF(" %s package found\n", apimodule);
239
v = PyObject_GetAttrString(mod, apiname);
243
DPRINTF(" API object %s found\n", apiname);
244
api = PyCObject_AsVoidPtr(v);
248
memcpy(&PySocketModule, api, sizeof(PySocketModule));
249
DPRINTF(" API object loaded and initialized.\n");
253
DPRINTF(" not found.\n");
259
#endif /* !PySocket_BUILDING_SOCKET */
264
#endif /* !Py__SOCKET_H */