blob: a1a212262a4fc0ac05e35b6fd47c458c02ffe1bc [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
5# include <sys/socket.h>
6# include <netinet/in.h>
7# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
8# include <netinet/tcp.h>
9# endif
10
11#else /* MS_WINDOWS */
12# include <winsock.h>
13#endif
14
15#ifdef HAVE_SYS_UN_H
16# include <sys/un.h>
17#else
18# undef AF_UNIX
19#endif
20
21#ifdef HAVE_NETPACKET_PACKET_H
22# include <sys/ioctl.h>
23# include <net/if.h>
24# include <netpacket/packet.h>
25#endif
26
27#ifndef Py__SOCKET_H
28#define Py__SOCKET_H
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/* Python module and C API name */
34#define PySocket_MODULE_NAME "_socket"
35#define PySocket_CAPI_NAME "CAPI"
36
37/* Abstract the socket file descriptor type */
38#ifdef MS_WINDOWS
39typedef SOCKET SOCKET_T;
40# ifdef MS_WIN64
41# define SIZEOF_SOCKET_T 8
42# else
43# define SIZEOF_SOCKET_T 4
44# endif
45#else
46typedef int SOCKET_T;
47# define SIZEOF_SOCKET_T SIZEOF_INT
48#endif
49
50/* The object holding a socket. It holds some extra information,
51 like the address family, which is used to decode socket address
52 arguments properly. */
53
54typedef struct {
55 PyObject_HEAD
56 SOCKET_T sock_fd; /* Socket file descriptor */
57 int sock_family; /* Address family, e.g., AF_INET */
58 int sock_type; /* Socket type, e.g., SOCK_STREAM */
59 int sock_proto; /* Protocol type, usually 0 */
60 union sock_addr {
61 struct sockaddr_in in;
62#ifdef AF_UNIX
63 struct sockaddr_un un;
64#endif
65#ifdef ENABLE_IPV6
66 struct sockaddr_in6 in6;
67 struct sockaddr_storage storage;
68#endif
69#ifdef HAVE_NETPACKET_PACKET_H
70 struct sockaddr_ll ll;
71#endif
72 } sock_addr;
Tim Peters6f5505a2002-02-17 03:58:51 +000073 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000074 errno, returns NULL and
75 sets a Python exception */
76} PySocketSockObject;
77
78/* A forward reference to the Socktype type object.
79 The Socktype variable contains pointers to various functions,
80 some of which call newsockobject(), which uses Socktype, so
81 there has to be a circular reference. */
82
83extern DL_IMPORT(PyTypeObject) PySocketSock_Type;
84
85/* --- C API ----------------------------------------------------*/
86
87/* C API for usage by other Python modules */
88typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +000089 PyTypeObject *Sock_Type;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000090} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +000091
92/* XXX The net effect of the following appears to be to define a function
93 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
94 XXX defined there directly. */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000095#ifndef PySocket_BUILDING_SOCKET
96
97/* --- C API ----------------------------------------------------*/
98
99/* Interfacestructure to C API for other modules.
100 Call PySocket_ImportModuleAPI() to initialize this
101 structure. After that usage is simple:
102
103 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
104 &PySocketModule.Sock_Type, (PyObject*)&Sock,
105 &key_file, &cert_file))
106 return NULL;
107 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000108*/
109
Tim Peters6f5505a2002-02-17 03:58:51 +0000110static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000111PySocketModule_APIObject PySocketModule;
112
113/* You *must* call this before using any of the functions in
114 PySocketModule and check its outcome; otherwise all accesses will
115 result in a segfault. Returns 0 on success. */
116
117#ifndef DPRINTF
118# define DPRINTF if (0) printf
119#endif
120
121static
122int PySocketModule_ImportModuleAndAPI(void)
123{
Tim Peters6f5505a2002-02-17 03:58:51 +0000124 PyObject *mod = 0, *v = 0;
125 char *apimodule = PySocket_MODULE_NAME;
126 char *apiname = PySocket_CAPI_NAME;
127 void *api;
128
129 DPRINTF("Importing the %s C API...\n", apimodule);
130 mod = PyImport_ImportModule(apimodule);
131 if (mod == NULL)
132 goto onError;
133 DPRINTF(" %s package found\n", apimodule);
134 v = PyObject_GetAttrString(mod, apiname);
135 if (v == NULL)
136 goto onError;
137 Py_DECREF(mod);
138 DPRINTF(" API object %s found\n", apiname);
139 api = PyCObject_AsVoidPtr(v);
140 if (api == NULL)
141 goto onError;
142 Py_DECREF(v);
143 memcpy(&PySocketModule, api, sizeof(PySocketModule));
144 DPRINTF(" API object loaded and initialized.\n");
145 return 0;
146
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000147 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000148 DPRINTF(" not found.\n");
149 Py_XDECREF(mod);
150 Py_XDECREF(v);
151 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000152}
153
Tim Peters6f5505a2002-02-17 03:58:51 +0000154#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000155
156#ifdef __cplusplus
157}
158#endif
159#endif /* !Py__SOCKET_H */