blob: 601c2820a59985b9b9e20ff777d1f4868b81dfae [file] [log] [blame]
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +00001/* Socket module header file */
2
3/* Includes needed for the sockaddr_* symbols below */
4#ifndef MS_WINDOWS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00005#ifdef __VMS
6# include <socket.h>
7# else
8# include <sys/socket.h>
9# endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000010# include <netinet/in.h>
11# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
12# include <netinet/tcp.h>
13# endif
14
15#else /* MS_WINDOWS */
Martin v. Löwis272cb402002-03-01 08:31:07 +000016#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
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000025# include <winsock.h>
26#endif
Martin v. Löwis272cb402002-03-01 08:31:07 +000027#endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000028
29#ifdef HAVE_SYS_UN_H
30# include <sys/un.h>
31#else
32# undef AF_UNIX
33#endif
34
Martin v. Löwis12af0482004-01-31 12:34:17 +000035#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
36#include <bluetooth/bluetooth.h>
37#include <bluetooth/rfcomm.h>
38#include <bluetooth/l2cap.h>
39#include <bluetooth/sco.h>
40#endif
41
Hye-Shik Chang96c446582004-02-02 08:48:45 +000042#ifdef HAVE_BLUETOOTH_H
43#include <bluetooth.h>
44#endif
45
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000046#ifdef HAVE_NETPACKET_PACKET_H
47# include <sys/ioctl.h>
48# include <net/if.h>
49# include <netpacket/packet.h>
50#endif
51
52#ifndef Py__SOCKET_H
53#define Py__SOCKET_H
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58/* Python module and C API name */
59#define PySocket_MODULE_NAME "_socket"
60#define PySocket_CAPI_NAME "CAPI"
61
62/* Abstract the socket file descriptor type */
63#ifdef MS_WINDOWS
64typedef SOCKET SOCKET_T;
65# ifdef MS_WIN64
66# define SIZEOF_SOCKET_T 8
67# else
68# define SIZEOF_SOCKET_T 4
69# endif
70#else
71typedef int SOCKET_T;
72# define SIZEOF_SOCKET_T SIZEOF_INT
73#endif
74
75/* The object holding a socket. It holds some extra information,
76 like the address family, which is used to decode socket address
77 arguments properly. */
78
79typedef struct {
80 PyObject_HEAD
81 SOCKET_T sock_fd; /* Socket file descriptor */
82 int sock_family; /* Address family, e.g., AF_INET */
83 int sock_type; /* Socket type, e.g., SOCK_STREAM */
84 int sock_proto; /* Protocol type, usually 0 */
85 union sock_addr {
86 struct sockaddr_in in;
87#ifdef AF_UNIX
88 struct sockaddr_un un;
89#endif
90#ifdef ENABLE_IPV6
91 struct sockaddr_in6 in6;
92 struct sockaddr_storage storage;
93#endif
Martin v. Löwis12af0482004-01-31 12:34:17 +000094#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
95 struct sockaddr_l2 bt_l2;
96 struct sockaddr_rc bt_rc;
97 struct sockaddr_sco bt_sco;
98#endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000099#ifdef HAVE_NETPACKET_PACKET_H
100 struct sockaddr_ll ll;
101#endif
102 } sock_addr;
Tim Peters6f5505a2002-02-17 03:58:51 +0000103 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000104 errno, returns NULL and
105 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000106 double sock_timeout; /* Operation timeout in seconds;
107 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000108} PySocketSockObject;
109
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000110/* --- C API ----------------------------------------------------*/
111
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000112/* Short explanation of what this C API export mechanism does
113 and how it works:
114
115 The _ssl module needs access to the type object defined in
116 the _socket module. Since cross-DLL linking introduces a lot of
117 problems on many platforms, the "trick" is to wrap the
118 C API of a module in a struct which then gets exported to
119 other modules via a PyCObject.
120
121 The code in socketmodule.c defines this struct (which currently
122 only contains the type object reference, but could very
123 well also include other C APIs needed by other modules)
124 and exports it as PyCObject via the module dictionary
125 under the name "CAPI".
126
127 Other modules can now include the socketmodule.h file
128 which defines the needed C APIs to import and set up
129 a static copy of this struct in the importing module.
130
131 After initialization, the importing module can then
132 access the C APIs from the _socket module by simply
133 referring to the static struct, e.g.
134
135 Load _socket module and its C API; this sets up the global
136 PySocketModule:
137
138 if (PySocketModule_ImportModuleAndAPI())
139 return;
140
141
142 Now use the C API as if it were defined in the using
143 module:
144
145 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
146
147 PySocketModule.Sock_Type,
148
149 (PyObject*)&Sock,
150 &key_file, &cert_file))
151 return NULL;
152
153 Support could easily be extended to export more C APIs/symbols
154 this way. Currently, only the type object is exported,
155 other candidates would be socket constructors and socket
156 access functions.
157
158*/
159
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000160/* C API for usage by other Python modules */
161typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000162 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000163 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000164} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000165
166/* XXX The net effect of the following appears to be to define a function
167 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000168 XXX defined there directly.
169
170 >>> It's defined here because other modules might also want to use
171 >>> the C API.
172
173*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000174#ifndef PySocket_BUILDING_SOCKET
175
176/* --- C API ----------------------------------------------------*/
177
178/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000179 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000180 structure. After that usage is simple:
181
182 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
183 &PySocketModule.Sock_Type, (PyObject*)&Sock,
184 &key_file, &cert_file))
185 return NULL;
186 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000187*/
188
Tim Peters6f5505a2002-02-17 03:58:51 +0000189static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000190PySocketModule_APIObject PySocketModule;
191
192/* You *must* call this before using any of the functions in
193 PySocketModule and check its outcome; otherwise all accesses will
194 result in a segfault. Returns 0 on success. */
195
196#ifndef DPRINTF
197# define DPRINTF if (0) printf
198#endif
199
200static
201int PySocketModule_ImportModuleAndAPI(void)
202{
Tim Peters6f5505a2002-02-17 03:58:51 +0000203 PyObject *mod = 0, *v = 0;
204 char *apimodule = PySocket_MODULE_NAME;
205 char *apiname = PySocket_CAPI_NAME;
206 void *api;
207
208 DPRINTF("Importing the %s C API...\n", apimodule);
209 mod = PyImport_ImportModule(apimodule);
210 if (mod == NULL)
211 goto onError;
212 DPRINTF(" %s package found\n", apimodule);
213 v = PyObject_GetAttrString(mod, apiname);
214 if (v == NULL)
215 goto onError;
216 Py_DECREF(mod);
217 DPRINTF(" API object %s found\n", apiname);
218 api = PyCObject_AsVoidPtr(v);
219 if (api == NULL)
220 goto onError;
221 Py_DECREF(v);
222 memcpy(&PySocketModule, api, sizeof(PySocketModule));
223 DPRINTF(" API object loaded and initialized.\n");
224 return 0;
225
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000226 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000227 DPRINTF(" not found.\n");
228 Py_XDECREF(mod);
229 Py_XDECREF(v);
230 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000231}
232
Tim Peters6f5505a2002-02-17 03:58:51 +0000233#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000234
235#ifdef __cplusplus
236}
237#endif
238#endif /* !Py__SOCKET_H */