blob: 384d5951541930414a92b262ed0bf5db8396aee4 [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 Chang96c44652004-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
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000075/* Socket address */
76typedef union sock_addr {
77 struct sockaddr_in in;
78#ifdef AF_UNIX
79 struct sockaddr_un un;
80#endif
81#ifdef ENABLE_IPV6
82 struct sockaddr_in6 in6;
83 struct sockaddr_storage storage;
84#endif
85#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
86 struct sockaddr_l2 bt_l2;
87 struct sockaddr_rc bt_rc;
88 struct sockaddr_sco bt_sco;
89#endif
90#ifdef HAVE_NETPACKET_PACKET_H
91 struct sockaddr_ll ll;
92#endif
93} sock_addr_t;
94
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000095/* The object holding a socket. It holds some extra information,
96 like the address family, which is used to decode socket address
97 arguments properly. */
98
99typedef struct {
100 PyObject_HEAD
101 SOCKET_T sock_fd; /* Socket file descriptor */
102 int sock_family; /* Address family, e.g., AF_INET */
103 int sock_type; /* Socket type, e.g., SOCK_STREAM */
104 int sock_proto; /* Protocol type, usually 0 */
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000105 sock_addr_t sock_addr; /* Socket address */
Tim Peters6f5505a2002-02-17 03:58:51 +0000106 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000107 errno, returns NULL and
108 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000109 double sock_timeout; /* Operation timeout in seconds;
110 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000111} PySocketSockObject;
112
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000113/* --- C API ----------------------------------------------------*/
114
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000115/* Short explanation of what this C API export mechanism does
116 and how it works:
117
118 The _ssl module needs access to the type object defined in
119 the _socket module. Since cross-DLL linking introduces a lot of
120 problems on many platforms, the "trick" is to wrap the
121 C API of a module in a struct which then gets exported to
122 other modules via a PyCObject.
123
124 The code in socketmodule.c defines this struct (which currently
125 only contains the type object reference, but could very
126 well also include other C APIs needed by other modules)
127 and exports it as PyCObject via the module dictionary
128 under the name "CAPI".
129
130 Other modules can now include the socketmodule.h file
131 which defines the needed C APIs to import and set up
132 a static copy of this struct in the importing module.
133
134 After initialization, the importing module can then
135 access the C APIs from the _socket module by simply
136 referring to the static struct, e.g.
137
138 Load _socket module and its C API; this sets up the global
139 PySocketModule:
140
141 if (PySocketModule_ImportModuleAndAPI())
142 return;
143
144
145 Now use the C API as if it were defined in the using
146 module:
147
148 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
149
150 PySocketModule.Sock_Type,
151
152 (PyObject*)&Sock,
153 &key_file, &cert_file))
154 return NULL;
155
156 Support could easily be extended to export more C APIs/symbols
157 this way. Currently, only the type object is exported,
158 other candidates would be socket constructors and socket
159 access functions.
160
161*/
162
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000163/* C API for usage by other Python modules */
164typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000165 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000166 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000167} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000168
169/* XXX The net effect of the following appears to be to define a function
170 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000171 XXX defined there directly.
172
173 >>> It's defined here because other modules might also want to use
174 >>> the C API.
175
176*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000177#ifndef PySocket_BUILDING_SOCKET
178
179/* --- C API ----------------------------------------------------*/
180
181/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000182 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000183 structure. After that usage is simple:
184
185 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
186 &PySocketModule.Sock_Type, (PyObject*)&Sock,
187 &key_file, &cert_file))
188 return NULL;
189 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000190*/
191
Tim Peters6f5505a2002-02-17 03:58:51 +0000192static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000193PySocketModule_APIObject PySocketModule;
194
195/* You *must* call this before using any of the functions in
196 PySocketModule and check its outcome; otherwise all accesses will
197 result in a segfault. Returns 0 on success. */
198
199#ifndef DPRINTF
200# define DPRINTF if (0) printf
201#endif
202
203static
204int PySocketModule_ImportModuleAndAPI(void)
205{
Tim Peters6f5505a2002-02-17 03:58:51 +0000206 PyObject *mod = 0, *v = 0;
207 char *apimodule = PySocket_MODULE_NAME;
208 char *apiname = PySocket_CAPI_NAME;
209 void *api;
210
211 DPRINTF("Importing the %s C API...\n", apimodule);
212 mod = PyImport_ImportModule(apimodule);
213 if (mod == NULL)
214 goto onError;
215 DPRINTF(" %s package found\n", apimodule);
216 v = PyObject_GetAttrString(mod, apiname);
217 if (v == NULL)
218 goto onError;
219 Py_DECREF(mod);
220 DPRINTF(" API object %s found\n", apiname);
221 api = PyCObject_AsVoidPtr(v);
222 if (api == NULL)
223 goto onError;
224 Py_DECREF(v);
225 memcpy(&PySocketModule, api, sizeof(PySocketModule));
226 DPRINTF(" API object loaded and initialized.\n");
227 return 0;
228
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000229 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000230 DPRINTF(" not found.\n");
231 Py_XDECREF(mod);
232 Py_XDECREF(v);
233 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000234}
235
Tim Peters6f5505a2002-02-17 03:58:51 +0000236#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000237
238#ifdef __cplusplus
239}
240#endif
241#endif /* !Py__SOCKET_H */