blob: 167d50711a2f0dfbf92280b4605f5e6080315f88 [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
35#ifdef HAVE_NETPACKET_PACKET_H
36# include <sys/ioctl.h>
37# include <net/if.h>
38# include <netpacket/packet.h>
39#endif
40
41#ifndef Py__SOCKET_H
42#define Py__SOCKET_H
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* Python module and C API name */
48#define PySocket_MODULE_NAME "_socket"
49#define PySocket_CAPI_NAME "CAPI"
50
51/* Abstract the socket file descriptor type */
52#ifdef MS_WINDOWS
53typedef SOCKET SOCKET_T;
54# ifdef MS_WIN64
55# define SIZEOF_SOCKET_T 8
56# else
57# define SIZEOF_SOCKET_T 4
58# endif
59#else
60typedef int SOCKET_T;
61# define SIZEOF_SOCKET_T SIZEOF_INT
62#endif
63
64/* The object holding a socket. It holds some extra information,
65 like the address family, which is used to decode socket address
66 arguments properly. */
67
68typedef struct {
69 PyObject_HEAD
70 SOCKET_T sock_fd; /* Socket file descriptor */
71 int sock_family; /* Address family, e.g., AF_INET */
72 int sock_type; /* Socket type, e.g., SOCK_STREAM */
73 int sock_proto; /* Protocol type, usually 0 */
74 union sock_addr {
75 struct sockaddr_in in;
76#ifdef AF_UNIX
77 struct sockaddr_un un;
78#endif
79#ifdef ENABLE_IPV6
80 struct sockaddr_in6 in6;
81 struct sockaddr_storage storage;
82#endif
83#ifdef HAVE_NETPACKET_PACKET_H
84 struct sockaddr_ll ll;
85#endif
86 } sock_addr;
Tim Peters6f5505a2002-02-17 03:58:51 +000087 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000088 errno, returns NULL and
89 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +000090 double sock_timeout; /* Operation timeout in seconds;
91 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000092} PySocketSockObject;
93
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000094/* --- C API ----------------------------------------------------*/
95
Marc-André Lemburg666e70d2002-02-25 14:45:40 +000096/* Short explanation of what this C API export mechanism does
97 and how it works:
98
99 The _ssl module needs access to the type object defined in
100 the _socket module. Since cross-DLL linking introduces a lot of
101 problems on many platforms, the "trick" is to wrap the
102 C API of a module in a struct which then gets exported to
103 other modules via a PyCObject.
104
105 The code in socketmodule.c defines this struct (which currently
106 only contains the type object reference, but could very
107 well also include other C APIs needed by other modules)
108 and exports it as PyCObject via the module dictionary
109 under the name "CAPI".
110
111 Other modules can now include the socketmodule.h file
112 which defines the needed C APIs to import and set up
113 a static copy of this struct in the importing module.
114
115 After initialization, the importing module can then
116 access the C APIs from the _socket module by simply
117 referring to the static struct, e.g.
118
119 Load _socket module and its C API; this sets up the global
120 PySocketModule:
121
122 if (PySocketModule_ImportModuleAndAPI())
123 return;
124
125
126 Now use the C API as if it were defined in the using
127 module:
128
129 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
130
131 PySocketModule.Sock_Type,
132
133 (PyObject*)&Sock,
134 &key_file, &cert_file))
135 return NULL;
136
137 Support could easily be extended to export more C APIs/symbols
138 this way. Currently, only the type object is exported,
139 other candidates would be socket constructors and socket
140 access functions.
141
142*/
143
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000144/* C API for usage by other Python modules */
145typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000146 PyTypeObject *Sock_Type;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000147} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000148
149/* XXX The net effect of the following appears to be to define a function
150 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000151 XXX defined there directly.
152
153 >>> It's defined here because other modules might also want to use
154 >>> the C API.
155
156*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000157#ifndef PySocket_BUILDING_SOCKET
158
159/* --- C API ----------------------------------------------------*/
160
161/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000162 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000163 structure. After that usage is simple:
164
165 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
166 &PySocketModule.Sock_Type, (PyObject*)&Sock,
167 &key_file, &cert_file))
168 return NULL;
169 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000170*/
171
Tim Peters6f5505a2002-02-17 03:58:51 +0000172static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000173PySocketModule_APIObject PySocketModule;
174
175/* You *must* call this before using any of the functions in
176 PySocketModule and check its outcome; otherwise all accesses will
177 result in a segfault. Returns 0 on success. */
178
179#ifndef DPRINTF
180# define DPRINTF if (0) printf
181#endif
182
183static
184int PySocketModule_ImportModuleAndAPI(void)
185{
Tim Peters6f5505a2002-02-17 03:58:51 +0000186 PyObject *mod = 0, *v = 0;
187 char *apimodule = PySocket_MODULE_NAME;
188 char *apiname = PySocket_CAPI_NAME;
189 void *api;
190
191 DPRINTF("Importing the %s C API...\n", apimodule);
192 mod = PyImport_ImportModule(apimodule);
193 if (mod == NULL)
194 goto onError;
195 DPRINTF(" %s package found\n", apimodule);
196 v = PyObject_GetAttrString(mod, apiname);
197 if (v == NULL)
198 goto onError;
199 Py_DECREF(mod);
200 DPRINTF(" API object %s found\n", apiname);
201 api = PyCObject_AsVoidPtr(v);
202 if (api == NULL)
203 goto onError;
204 Py_DECREF(v);
205 memcpy(&PySocketModule, api, sizeof(PySocketModule));
206 DPRINTF(" API object loaded and initialized.\n");
207 return 0;
208
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000209 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000210 DPRINTF(" not found.\n");
211 Py_XDECREF(mod);
212 Py_XDECREF(v);
213 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000214}
215
Tim Peters6f5505a2002-02-17 03:58:51 +0000216#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000217
218#ifdef __cplusplus
219}
220#endif
221#endif /* !Py__SOCKET_H */