blob: 65e1826eba648ca28ff192ffcecb95ed8b66b3db [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /* Perform runtime testing for a broken poll on OSX to make it easier
12 * to use the same binary on multiple releases of the OS.
13 */
14#undef HAVE_BROKEN_POLL
15#endif
16
Tim Petersd92dfe02000-12-12 01:18:41 +000017/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
18 64 is too small (too many people have bumped into that limit).
19 Here we boost it.
20 Users who want even more than the boosted limit should #define
21 FD_SETSIZE higher before this; e.g., via compiler /D switch.
22*/
23#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
24#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000026
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000027#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#elif defined(HAVE_SYS_POLL_H)
30#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000031#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000032
Guido van Rossum37273171996-12-09 18:47:43 +000033#ifdef __sgi
34/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000035extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000036#endif
37
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000040#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000041
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000042#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000043#include <sys/time.h>
44#include <utils.h>
45#endif
46
Guido van Rossum6f489d91996-06-28 20:15:15 +000047#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000048# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000050#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000052# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053# include <socket.h>
54# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000057static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000058
Barry Warsawc1cb3601996-12-12 22:16:21 +000059/* list of Python objects and their file descriptor */
60typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 PyObject *obj; /* owned reference */
62 SOCKET fd;
63 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000064} pylist;
65
Barry Warsawc1cb3601996-12-12 22:16:21 +000066static void
Tim Peters4b046c22001-08-16 21:59:46 +000067reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 int i;
70 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
71 Py_XDECREF(fd2obj[i].obj);
72 fd2obj[i].obj = NULL;
73 }
74 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000075}
76
77
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000078/* returns -1 and sets the Python exception if an error occurred, otherwise
79 returns a number >= 0
80*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000081static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000082seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 int max = -1;
85 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000086 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 PyObject* fast_seq = NULL;
88 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
91 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000092
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000093 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 if (!fast_seq)
95 return -1;
96
97 len = PySequence_Fast_GET_SIZE(fast_seq);
98
99 for (i = 0; i < len; i++) {
100 SOCKET v;
101
102 /* any intervening fileno() calls could decr this refcnt */
103 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104 return -1;
105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 Py_INCREF(o);
107 v = PyObject_AsFileDescriptor( o );
108 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000109
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000110#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112#else /* !_MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 if (v < 0 || v >= FD_SETSIZE) {
114 PyErr_SetString(PyExc_ValueError,
115 "filedescriptor out of range in select()");
116 goto finally;
117 }
118 if (v > max)
119 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000120#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 /* add object and its file descriptor to the list */
124 if (index >= FD_SETSIZE) {
125 PyErr_SetString(PyExc_ValueError,
126 "too many file descriptors in select()");
127 goto finally;
128 }
129 fd2obj[index].obj = o;
130 fd2obj[index].fd = v;
131 fd2obj[index].sentinel = 0;
132 fd2obj[++index].sentinel = -1;
133 }
134 Py_DECREF(fast_seq);
135 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000136
137 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 Py_XDECREF(o);
139 Py_DECREF(fast_seq);
140 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000141}
142
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143/* returns NULL and sets the Python exception if an error occurred */
144static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000145set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 int i, j, count=0;
148 PyObject *list, *o;
149 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
152 if (FD_ISSET(fd2obj[j].fd, set))
153 count++;
154 }
155 list = PyList_New(count);
156 if (!list)
157 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 i = 0;
160 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
161 fd = fd2obj[j].fd;
162 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000163#ifndef _MSC_VER
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 if (fd > FD_SETSIZE) {
165 PyErr_SetString(PyExc_SystemError,
166 "filedescriptor out of range returned in select()");
167 goto finally;
168 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000169#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 o = fd2obj[j].obj;
171 fd2obj[j].obj = NULL;
172 /* transfer ownership */
173 if (PyList_SetItem(list, i, o) < 0)
174 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 i++;
177 }
178 }
179 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000180 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 Py_DECREF(list);
182 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000183}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000184
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#undef SELECT_USES_HEAP
186#if FD_SETSIZE > 1024
187#define SELECT_USES_HEAP
188#endif /* FD_SETSIZE > 1024 */
189
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000190static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000191select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000192{
Barry Warsawb44740f2001-08-16 16:52:59 +0000193#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000195#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 /* XXX: All this should probably be implemented as follows:
197 * - find the highest descriptor we're interested in
198 * - add one
199 * - that's the size
200 * See: Stevens, APitUE, $12.5.1
201 */
202 pylist rfd2obj[FD_SETSIZE + 1];
203 pylist wfd2obj[FD_SETSIZE + 1];
204 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000205#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 PyObject *ifdlist, *ofdlist, *efdlist;
207 PyObject *ret = NULL;
208 PyObject *tout = Py_None;
209 fd_set ifdset, ofdset, efdset;
210 double timeout;
211 struct timeval tv, *tvp;
212 long seconds;
213 int imax, omax, emax, max;
214 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 /* convert arguments */
217 if (!PyArg_UnpackTuple(args, "select", 3, 4,
218 &ifdlist, &ofdlist, &efdlist, &tout))
219 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 if (tout == Py_None)
222 tvp = (struct timeval *)0;
223 else if (!PyNumber_Check(tout)) {
224 PyErr_SetString(PyExc_TypeError,
225 "timeout must be a float or None");
226 return NULL;
227 }
228 else {
229 timeout = PyFloat_AsDouble(tout);
230 if (timeout == -1 && PyErr_Occurred())
231 return NULL;
232 if (timeout > (double)LONG_MAX) {
233 PyErr_SetString(PyExc_OverflowError,
234 "timeout period too long");
235 return NULL;
236 }
237 seconds = (long)timeout;
238 timeout = timeout - (double)seconds;
239 tv.tv_sec = seconds;
240 tv.tv_usec = (long)(timeout * 1E6);
241 tvp = &tv;
242 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000243
Guido van Rossumed233a51992-06-23 09:07:03 +0000244
Barry Warsawb44740f2001-08-16 16:52:59 +0000245#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 /* Allocate memory for the lists */
247 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
248 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
249 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
250 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
251 if (rfd2obj) PyMem_DEL(rfd2obj);
252 if (wfd2obj) PyMem_DEL(wfd2obj);
253 if (efd2obj) PyMem_DEL(efd2obj);
254 return PyErr_NoMemory();
255 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000256#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 /* Convert sequences to fd_sets, and get maximum fd number
258 * propagates the Python exception set in seq2set()
259 */
260 rfd2obj[0].sentinel = -1;
261 wfd2obj[0].sentinel = -1;
262 efd2obj[0].sentinel = -1;
263 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
264 goto finally;
265 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
266 goto finally;
267 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
268 goto finally;
269 max = imax;
270 if (omax > max) max = omax;
271 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 Py_BEGIN_ALLOW_THREADS
274 n = select(max, &ifdset, &ofdset, &efdset, tvp);
275 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000276
Thomas Heller106f4c72002-09-24 16:51:00 +0000277#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 if (n == SOCKET_ERROR) {
279 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
280 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000281#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 if (n < 0) {
283 PyErr_SetFromErrno(SelectError);
284 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000285#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 else {
287 /* any of these three calls can raise an exception. it's more
288 convenient to test for this after all three calls... but
289 is that acceptable?
290 */
291 ifdlist = set2list(&ifdset, rfd2obj);
292 ofdlist = set2list(&ofdset, wfd2obj);
293 efdlist = set2list(&efdset, efd2obj);
294 if (PyErr_Occurred())
295 ret = NULL;
296 else
297 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 Py_DECREF(ifdlist);
300 Py_DECREF(ofdlist);
301 Py_DECREF(efdlist);
302 }
303
Barry Warsawc1cb3601996-12-12 22:16:21 +0000304 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 reap_obj(rfd2obj);
306 reap_obj(wfd2obj);
307 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000308#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 PyMem_DEL(rfd2obj);
310 PyMem_DEL(wfd2obj);
311 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000312#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000314}
315
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000316#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000318 * poll() support
319 */
320
321typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 PyObject_HEAD
323 PyObject *dict;
324 int ufd_uptodate;
325 int ufd_len;
326 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000327} pollObject;
328
Jeremy Hylton938ace62002-07-17 16:30:39 +0000329static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000332 contained within a pollObject. Return 1 on success, 0 on an error.
333*/
334
335static int
336update_ufd_array(pollObject *self)
337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 Py_ssize_t i, pos;
339 PyObject *key, *value;
340 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 self->ufd_len = PyDict_Size(self->dict);
343 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
344 if (self->ufds == NULL) {
345 self->ufds = old_ufds;
346 PyErr_NoMemory();
347 return 0;
348 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 i = pos = 0;
351 while (PyDict_Next(self->dict, &pos, &key, &value)) {
352 self->ufds[i].fd = PyLong_AsLong(key);
353 self->ufds[i].events = (short)PyLong_AsLong(value);
354 i++;
355 }
356 self->ufd_uptodate = 1;
357 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000358}
359
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000360PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000361"register(fd [, eventmask] ) -> None\n\n\
362Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000363fd -- either an integer, or an object with a fileno() method returning an\n\
364 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000365events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366
367static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 PyObject *o, *key, *value;
371 int fd, events = POLLIN | POLLPRI | POLLOUT;
372 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
375 return NULL;
376 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 fd = PyObject_AsFileDescriptor(o);
379 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 /* Add entry to the internal dictionary: the key is the
382 file descriptor, and the value is the event mask. */
383 key = PyLong_FromLong(fd);
384 if (key == NULL)
385 return NULL;
386 value = PyLong_FromLong(events);
387 if (value == NULL) {
388 Py_DECREF(key);
389 return NULL;
390 }
391 err = PyDict_SetItem(self->dict, key, value);
392 Py_DECREF(key);
393 Py_DECREF(value);
394 if (err < 0)
395 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 self->ufd_uptodate = 0;
398
399 Py_INCREF(Py_None);
400 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401}
402
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000403PyDoc_STRVAR(poll_modify_doc,
404"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000405Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000406fd -- either an integer, or an object with a fileno() method returning an\n\
407 int.\n\
408events -- an optional bitmask describing the type of events to check for");
409
410static PyObject *
411poll_modify(pollObject *self, PyObject *args)
412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 PyObject *o, *key, *value;
414 int fd, events;
415 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
418 return NULL;
419 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 fd = PyObject_AsFileDescriptor(o);
422 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 /* Modify registered fd */
425 key = PyLong_FromLong(fd);
426 if (key == NULL)
427 return NULL;
428 if (PyDict_GetItem(self->dict, key) == NULL) {
429 errno = ENOENT;
430 PyErr_SetFromErrno(PyExc_IOError);
431 return NULL;
432 }
433 value = PyLong_FromLong(events);
434 if (value == NULL) {
435 Py_DECREF(key);
436 return NULL;
437 }
438 err = PyDict_SetItem(self->dict, key, value);
439 Py_DECREF(key);
440 Py_DECREF(value);
441 if (err < 0)
442 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 self->ufd_uptodate = 0;
445
446 Py_INCREF(Py_None);
447 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000448}
449
450
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000451PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000453Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000454
455static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 PyObject *key;
459 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 fd = PyObject_AsFileDescriptor( o );
462 if (fd == -1)
463 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 /* Check whether the fd is already in the array */
466 key = PyLong_FromLong(fd);
467 if (key == NULL)
468 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 if (PyDict_DelItem(self->dict, key) == -1) {
471 Py_DECREF(key);
472 /* This will simply raise the KeyError set by PyDict_DelItem
473 if the file descriptor isn't registered. */
474 return NULL;
475 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 Py_DECREF(key);
478 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 Py_INCREF(Py_None);
481 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000482}
483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000485"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
486Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000487any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
489static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 PyObject *result_list = NULL, *tout = NULL;
493 int timeout = 0, poll_result, i, j;
494 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
497 return NULL;
498 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Check values for timeout */
501 if (tout == NULL || tout == Py_None)
502 timeout = -1;
503 else if (!PyNumber_Check(tout)) {
504 PyErr_SetString(PyExc_TypeError,
505 "timeout must be an integer or None");
506 return NULL;
507 }
508 else {
509 tout = PyNumber_Long(tout);
510 if (!tout)
511 return NULL;
512 timeout = PyLong_AsLong(tout);
513 Py_DECREF(tout);
514 if (timeout == -1 && PyErr_Occurred())
515 return NULL;
516 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 /* Ensure the ufd array is up to date */
519 if (!self->ufd_uptodate)
520 if (update_ufd_array(self) == 0)
521 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 /* call poll() */
524 Py_BEGIN_ALLOW_THREADS
525 poll_result = poll(self->ufds, self->ufd_len, timeout);
526 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 if (poll_result < 0) {
529 PyErr_SetFromErrno(SelectError);
530 return NULL;
531 }
532
533 /* build the result list */
534
535 result_list = PyList_New(poll_result);
536 if (!result_list)
537 return NULL;
538 else {
539 for (i = 0, j = 0; j < poll_result; j++) {
540 /* skip to the next fired descriptor */
541 while (!self->ufds[i].revents) {
542 i++;
543 }
544 /* if we hit a NULL return, set value to NULL
545 and break out of loop; code at end will
546 clean up result_list */
547 value = PyTuple_New(2);
548 if (value == NULL)
549 goto error;
550 num = PyLong_FromLong(self->ufds[i].fd);
551 if (num == NULL) {
552 Py_DECREF(value);
553 goto error;
554 }
555 PyTuple_SET_ITEM(value, 0, num);
556
557 /* The &0xffff is a workaround for AIX. 'revents'
558 is a 16-bit short, and IBM assigned POLLNVAL
559 to be 0x8000, so the conversion to int results
560 in a negative number. See SF bug #923315. */
561 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
562 if (num == NULL) {
563 Py_DECREF(value);
564 goto error;
565 }
566 PyTuple_SET_ITEM(value, 1, num);
567 if ((PyList_SetItem(result_list, j, value)) == -1) {
568 Py_DECREF(value);
569 goto error;
570 }
571 i++;
572 }
573 }
574 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000575
576 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 Py_DECREF(result_list);
578 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000579}
580
581static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 {"register", (PyCFunction)poll_register,
583 METH_VARARGS, poll_register_doc},
584 {"modify", (PyCFunction)poll_modify,
585 METH_VARARGS, poll_modify_doc},
586 {"unregister", (PyCFunction)poll_unregister,
587 METH_O, poll_unregister_doc},
588 {"poll", (PyCFunction)poll_poll,
589 METH_VARARGS, poll_poll_doc},
590 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000591};
592
593static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000594newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000595{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 pollObject *self;
597 self = PyObject_New(pollObject, &poll_Type);
598 if (self == NULL)
599 return NULL;
600 /* ufd_uptodate is a Boolean, denoting whether the
601 array pointed to by ufds matches the contents of the dictionary. */
602 self->ufd_uptodate = 0;
603 self->ufds = NULL;
604 self->dict = PyDict_New();
605 if (self->dict == NULL) {
606 Py_DECREF(self);
607 return NULL;
608 }
609 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000610}
611
612static void
613poll_dealloc(pollObject *self)
614{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 if (self->ufds != NULL)
616 PyMem_DEL(self->ufds);
617 Py_XDECREF(self->dict);
618 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000619}
620
Tim Peters0c322792002-07-17 16:49:03 +0000621static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 /* The ob_type field must be initialized in the module init function
623 * to be portable to Windows without using C++. */
624 PyVarObject_HEAD_INIT(NULL, 0)
625 "select.poll", /*tp_name*/
626 sizeof(pollObject), /*tp_basicsize*/
627 0, /*tp_itemsize*/
628 /* methods */
629 (destructor)poll_dealloc, /*tp_dealloc*/
630 0, /*tp_print*/
631 0, /*tp_getattr*/
632 0, /*tp_setattr*/
633 0, /*tp_reserved*/
634 0, /*tp_repr*/
635 0, /*tp_as_number*/
636 0, /*tp_as_sequence*/
637 0, /*tp_as_mapping*/
638 0, /*tp_hash*/
639 0, /*tp_call*/
640 0, /*tp_str*/
641 0, /*tp_getattro*/
642 0, /*tp_setattro*/
643 0, /*tp_as_buffer*/
644 Py_TPFLAGS_DEFAULT, /*tp_flags*/
645 0, /*tp_doc*/
646 0, /*tp_traverse*/
647 0, /*tp_clear*/
648 0, /*tp_richcompare*/
649 0, /*tp_weaklistoffset*/
650 0, /*tp_iter*/
651 0, /*tp_iternext*/
652 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000653};
654
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000655PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000656"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000657unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658
659static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000660select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000663}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000664
665#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000667 * On some systems poll() sets errno on invalid file descriptors. We test
668 * for this at runtime because this bug may be fixed or introduced between
669 * OS releases.
670 */
671static int select_have_broken_poll(void)
672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 int poll_test;
674 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 /* Create a file descriptor to make invalid */
679 if (pipe(filedes) < 0) {
680 return 1;
681 }
682 poll_struct.fd = filedes[0];
683 close(filedes[0]);
684 close(filedes[1]);
685 poll_test = poll(&poll_struct, 1, 0);
686 if (poll_test < 0) {
687 return 1;
688 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
689 return 1;
690 }
691 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692}
693#endif /* __APPLE__ */
694
695#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000696
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000697#ifdef HAVE_EPOLL
698/* **************************************************************************
699 * epoll interface for Linux 2.6
700 *
701 * Written by Christian Heimes
702 * Inspired by Twisted's _epoll.pyx and select.poll()
703 */
704
705#ifdef HAVE_SYS_EPOLL_H
706#include <sys/epoll.h>
707#endif
708
709typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 PyObject_HEAD
711 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000712} pyEpoll_Object;
713
714static PyTypeObject pyEpoll_Type;
715#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
716
717static PyObject *
718pyepoll_err_closed(void)
719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
721 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000722}
723
724static int
725pyepoll_internal_close(pyEpoll_Object *self)
726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 int save_errno = 0;
728 if (self->epfd >= 0) {
729 int epfd = self->epfd;
730 self->epfd = -1;
731 Py_BEGIN_ALLOW_THREADS
732 if (close(epfd) < 0)
733 save_errno = errno;
734 Py_END_ALLOW_THREADS
735 }
736 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000737}
738
739static PyObject *
740newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 if (sizehint == -1) {
745 sizehint = FD_SETSIZE-1;
746 }
747 else if (sizehint < 1) {
748 PyErr_Format(PyExc_ValueError,
749 "sizehint must be greater zero, got %d",
750 sizehint);
751 return NULL;
752 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 assert(type != NULL && type->tp_alloc != NULL);
755 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
756 if (self == NULL)
757 return NULL;
758
759 if (fd == -1) {
760 Py_BEGIN_ALLOW_THREADS
761 self->epfd = epoll_create(sizehint);
762 Py_END_ALLOW_THREADS
763 }
764 else {
765 self->epfd = fd;
766 }
767 if (self->epfd < 0) {
768 Py_DECREF(self);
769 PyErr_SetFromErrno(PyExc_IOError);
770 return NULL;
771 }
772 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000773}
774
775
776static PyObject *
777pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 int sizehint = -1;
780 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
783 &sizehint))
784 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000787}
788
789
790static void
791pyepoll_dealloc(pyEpoll_Object *self)
792{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 (void)pyepoll_internal_close(self);
794 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000795}
796
797static PyObject*
798pyepoll_close(pyEpoll_Object *self)
799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 errno = pyepoll_internal_close(self);
801 if (errno < 0) {
802 PyErr_SetFromErrno(PyExc_IOError);
803 return NULL;
804 }
805 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000806}
807
808PyDoc_STRVAR(pyepoll_close_doc,
809"close() -> None\n\
810\n\
811Close the epoll control file descriptor. Further operations on the epoll\n\
812object will raise an exception.");
813
814static PyObject*
815pyepoll_get_closed(pyEpoll_Object *self)
816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 if (self->epfd < 0)
818 Py_RETURN_TRUE;
819 else
820 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000821}
822
823static PyObject*
824pyepoll_fileno(pyEpoll_Object *self)
825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 if (self->epfd < 0)
827 return pyepoll_err_closed();
828 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000829}
830
831PyDoc_STRVAR(pyepoll_fileno_doc,
832"fileno() -> int\n\
833\n\
834Return the epoll control file descriptor.");
835
836static PyObject*
837pyepoll_fromfd(PyObject *cls, PyObject *args)
838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
842 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000845}
846
847PyDoc_STRVAR(pyepoll_fromfd_doc,
848"fromfd(fd) -> epoll\n\
849\n\
850Create an epoll object from a given control fd.");
851
852static PyObject *
853pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 struct epoll_event ev;
856 int result;
857 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 if (epfd < 0)
860 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 fd = PyObject_AsFileDescriptor(pfd);
863 if (fd == -1) {
864 return NULL;
865 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 switch(op) {
868 case EPOLL_CTL_ADD:
869 case EPOLL_CTL_MOD:
870 ev.events = events;
871 ev.data.fd = fd;
872 Py_BEGIN_ALLOW_THREADS
873 result = epoll_ctl(epfd, op, fd, &ev);
874 Py_END_ALLOW_THREADS
875 break;
876 case EPOLL_CTL_DEL:
877 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
878 * operation required a non-NULL pointer in event, even
879 * though this argument is ignored. */
880 Py_BEGIN_ALLOW_THREADS
881 result = epoll_ctl(epfd, op, fd, &ev);
882 if (errno == EBADF) {
883 /* fd already closed */
884 result = 0;
885 errno = 0;
886 }
887 Py_END_ALLOW_THREADS
888 break;
889 default:
890 result = -1;
891 errno = EINVAL;
892 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 if (result < 0) {
895 PyErr_SetFromErrno(PyExc_IOError);
896 return NULL;
897 }
898 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000899}
900
901static PyObject *
902pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
903{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 PyObject *pfd;
905 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
906 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
909 &pfd, &events)) {
910 return NULL;
911 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000914}
915
916PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000917"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000918\n\
Georg Brandl222569d2010-08-02 20:47:56 +0000919Registers a new fd or modifies an already registered fd.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000920fd is the target file descriptor of the operation.\n\
921events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000922is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
923\n\
924The epoll interface supports all file descriptors that support poll.");
925
926static PyObject *
927pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
928{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 PyObject *pfd;
930 unsigned int events;
931 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
934 &pfd, &events)) {
935 return NULL;
936 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000939}
940
941PyDoc_STRVAR(pyepoll_modify_doc,
942"modify(fd, eventmask) -> None\n\
943\n\
944fd is the target file descriptor of the operation\n\
945events is a bit set composed of the various EPOLL constants");
946
947static PyObject *
948pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
949{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 PyObject *pfd;
951 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
954 &pfd)) {
955 return NULL;
956 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000959}
960
961PyDoc_STRVAR(pyepoll_unregister_doc,
962"unregister(fd) -> None\n\
963\n\
964fd is the target file descriptor of the operation.");
965
966static PyObject *
967pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 double dtimeout = -1.;
970 int timeout;
971 int maxevents = -1;
972 int nfds, i;
973 PyObject *elist = NULL, *etuple = NULL;
974 struct epoll_event *evs = NULL;
975 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 if (self->epfd < 0)
978 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
981 &dtimeout, &maxevents)) {
982 return NULL;
983 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 if (dtimeout < 0) {
986 timeout = -1;
987 }
988 else if (dtimeout * 1000.0 > INT_MAX) {
989 PyErr_SetString(PyExc_OverflowError,
990 "timeout is too large");
991 return NULL;
992 }
993 else {
994 timeout = (int)(dtimeout * 1000.0);
995 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 if (maxevents == -1) {
998 maxevents = FD_SETSIZE-1;
999 }
1000 else if (maxevents < 1) {
1001 PyErr_Format(PyExc_ValueError,
1002 "maxevents must be greater than 0, got %d",
1003 maxevents);
1004 return NULL;
1005 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 evs = PyMem_New(struct epoll_event, maxevents);
1008 if (evs == NULL) {
1009 Py_DECREF(self);
1010 PyErr_NoMemory();
1011 return NULL;
1012 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 Py_BEGIN_ALLOW_THREADS
1015 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1016 Py_END_ALLOW_THREADS
1017 if (nfds < 0) {
1018 PyErr_SetFromErrno(PyExc_IOError);
1019 goto error;
1020 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 elist = PyList_New(nfds);
1023 if (elist == NULL) {
1024 goto error;
1025 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 for (i = 0; i < nfds; i++) {
1028 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1029 if (etuple == NULL) {
1030 Py_CLEAR(elist);
1031 goto error;
1032 }
1033 PyList_SET_ITEM(elist, i, etuple);
1034 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001035
Christian Heimesf6cd9672008-03-26 13:45:42 +00001036 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 PyMem_Free(evs);
1038 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001039}
1040
1041PyDoc_STRVAR(pyepoll_poll_doc,
1042"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1043\n\
1044Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1045in seconds (as float). -1 makes poll wait indefinitely.\n\
1046Up to maxevents are returned to the caller.");
1047
1048static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 {"fromfd", (PyCFunction)pyepoll_fromfd,
1050 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1051 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1052 pyepoll_close_doc},
1053 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1054 pyepoll_fileno_doc},
1055 {"modify", (PyCFunction)pyepoll_modify,
1056 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1057 {"register", (PyCFunction)pyepoll_register,
1058 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1059 {"unregister", (PyCFunction)pyepoll_unregister,
1060 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1061 {"poll", (PyCFunction)pyepoll_poll,
1062 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1063 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001064};
1065
1066static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 {"closed", (getter)pyepoll_get_closed, NULL,
1068 "True if the epoll handler is closed"},
1069 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001070};
1071
1072PyDoc_STRVAR(pyepoll_doc,
1073"select.epoll([sizehint=-1])\n\
1074\n\
1075Returns an epolling object\n\
1076\n\
1077sizehint must be a positive integer or -1 for the default size. The\n\
1078sizehint is used to optimize internal data structures. It doesn't limit\n\
1079the maximum number of monitored events.");
1080
1081static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 PyVarObject_HEAD_INIT(NULL, 0)
1083 "select.epoll", /* tp_name */
1084 sizeof(pyEpoll_Object), /* tp_basicsize */
1085 0, /* tp_itemsize */
1086 (destructor)pyepoll_dealloc, /* tp_dealloc */
1087 0, /* tp_print */
1088 0, /* tp_getattr */
1089 0, /* tp_setattr */
1090 0, /* tp_reserved */
1091 0, /* tp_repr */
1092 0, /* tp_as_number */
1093 0, /* tp_as_sequence */
1094 0, /* tp_as_mapping */
1095 0, /* tp_hash */
1096 0, /* tp_call */
1097 0, /* tp_str */
1098 PyObject_GenericGetAttr, /* tp_getattro */
1099 0, /* tp_setattro */
1100 0, /* tp_as_buffer */
1101 Py_TPFLAGS_DEFAULT, /* tp_flags */
1102 pyepoll_doc, /* tp_doc */
1103 0, /* tp_traverse */
1104 0, /* tp_clear */
1105 0, /* tp_richcompare */
1106 0, /* tp_weaklistoffset */
1107 0, /* tp_iter */
1108 0, /* tp_iternext */
1109 pyepoll_methods, /* tp_methods */
1110 0, /* tp_members */
1111 pyepoll_getsetlist, /* tp_getset */
1112 0, /* tp_base */
1113 0, /* tp_dict */
1114 0, /* tp_descr_get */
1115 0, /* tp_descr_set */
1116 0, /* tp_dictoffset */
1117 0, /* tp_init */
1118 0, /* tp_alloc */
1119 pyepoll_new, /* tp_new */
1120 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001121};
1122
1123#endif /* HAVE_EPOLL */
1124
1125#ifdef HAVE_KQUEUE
1126/* **************************************************************************
1127 * kqueue interface for BSD
1128 *
1129 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1130 * All rights reserved.
1131 *
1132 * Redistribution and use in source and binary forms, with or without
1133 * modification, are permitted provided that the following conditions
1134 * are met:
1135 * 1. Redistributions of source code must retain the above copyright
1136 * notice, this list of conditions and the following disclaimer.
1137 * 2. Redistributions in binary form must reproduce the above copyright
1138 * notice, this list of conditions and the following disclaimer in the
1139 * documentation and/or other materials provided with the distribution.
1140 *
1141 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1142 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1143 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1144 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1145 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1146 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1147 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1148 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1149 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1150 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1151 * SUCH DAMAGE.
1152 */
1153
1154#ifdef HAVE_SYS_EVENT_H
1155#include <sys/event.h>
1156#endif
1157
1158PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001159"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001160\n\
1161This object is the equivalent of the struct kevent for the C API.\n\
1162\n\
1163See the kqueue manpage for more detailed information about the meaning\n\
1164of the arguments.\n\
1165\n\
1166One minor note: while you might hope that udata could store a\n\
1167reference to a python object, it cannot, because it is impossible to\n\
1168keep a proper reference count of the object once it's passed into the\n\
1169kernel. Therefore, I have restricted it to only storing an integer. I\n\
1170recommend ignoring it and simply using the 'ident' field to key off\n\
1171of. You could also set up a dictionary on the python side to store a\n\
1172udata->object mapping.");
1173
1174typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 PyObject_HEAD
1176 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001177} kqueue_event_Object;
1178
1179static PyTypeObject kqueue_event_Type;
1180
1181#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1182
1183typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 PyObject_HEAD
1185 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001186} kqueue_queue_Object;
1187
1188static PyTypeObject kqueue_queue_Type;
1189
1190#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1191
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001192#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1193# error uintptr_t does not match void *!
1194#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1195# define T_UINTPTRT T_ULONGLONG
1196# define T_INTPTRT T_LONGLONG
1197# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1198# define UINTPTRT_FMT_UNIT "K"
1199# define INTPTRT_FMT_UNIT "L"
1200#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1201# define T_UINTPTRT T_ULONG
1202# define T_INTPTRT T_LONG
1203# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1204# define UINTPTRT_FMT_UNIT "k"
1205# define INTPTRT_FMT_UNIT "l"
1206#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1207# define T_UINTPTRT T_UINT
1208# define T_INTPTRT T_INT
1209# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1210# define UINTPTRT_FMT_UNIT "I"
1211# define INTPTRT_FMT_UNIT "i"
1212#else
1213# error uintptr_t does not match int, long, or long long!
1214#endif
1215
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216/* Unfortunately, we can't store python objects in udata, because
1217 * kevents in the kernel can be removed without warning, which would
1218 * forever lose the refcount on the object stored with it.
1219 */
1220
1221#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1222static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1224 {"filter", T_SHORT, KQ_OFF(e.filter)},
1225 {"flags", T_USHORT, KQ_OFF(e.flags)},
1226 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1227 {"data", T_INTPTRT, KQ_OFF(e.data)},
1228 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1229 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001230};
1231#undef KQ_OFF
1232
1233static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001234
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001235kqueue_event_repr(kqueue_event_Object *s)
1236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 char buf[1024];
1238 PyOS_snprintf(
1239 buf, sizeof(buf),
1240 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1241 "data=0x%zd udata=%p>",
1242 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1243 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1244 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001245}
1246
1247static int
1248kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 PyObject *pfd;
1251 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1252 "data", "udata", NULL};
1253 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1258 &pfd, &(self->e.filter), &(self->e.flags),
1259 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1260 return -1;
1261 }
1262
1263 if (PyLong_Check(pfd)) {
1264 self->e.ident = PyLong_AsUintptr_t(pfd);
1265 }
1266 else {
1267 self->e.ident = PyObject_AsFileDescriptor(pfd);
1268 }
1269 if (PyErr_Occurred()) {
1270 return -1;
1271 }
1272 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001273}
1274
1275static PyObject *
1276kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 if (!kqueue_event_Check(o)) {
1282 if (op == Py_EQ || op == Py_NE) {
1283 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1284 Py_INCREF(res);
1285 return res;
1286 }
1287 PyErr_Format(PyExc_TypeError,
1288 "can't compare %.200s to %.200s",
1289 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1290 return NULL;
1291 }
1292 if (((result = s->e.ident - o->e.ident) == 0) &&
1293 ((result = s->e.filter - o->e.filter) == 0) &&
1294 ((result = s->e.flags - o->e.flags) == 0) &&
1295 ((result = s->e.fflags - o->e.fflags) == 0) &&
1296 ((result = s->e.data - o->e.data) == 0) &&
1297 ((result = s->e.udata - o->e.udata) == 0)
1298 ) {
1299 result = 0;
1300 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 switch (op) {
1303 case Py_EQ:
1304 result = (result == 0);
1305 break;
1306 case Py_NE:
1307 result = (result != 0);
1308 break;
1309 case Py_LE:
1310 result = (result <= 0);
1311 break;
1312 case Py_GE:
1313 result = (result >= 0);
1314 break;
1315 case Py_LT:
1316 result = (result < 0);
1317 break;
1318 case Py_GT:
1319 result = (result > 0);
1320 break;
1321 }
1322 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001323}
1324
1325static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 PyVarObject_HEAD_INIT(NULL, 0)
1327 "select.kevent", /* tp_name */
1328 sizeof(kqueue_event_Object), /* tp_basicsize */
1329 0, /* tp_itemsize */
1330 0, /* tp_dealloc */
1331 0, /* tp_print */
1332 0, /* tp_getattr */
1333 0, /* tp_setattr */
1334 0, /* tp_reserved */
1335 (reprfunc)kqueue_event_repr, /* tp_repr */
1336 0, /* tp_as_number */
1337 0, /* tp_as_sequence */
1338 0, /* tp_as_mapping */
1339 0, /* tp_hash */
1340 0, /* tp_call */
1341 0, /* tp_str */
1342 0, /* tp_getattro */
1343 0, /* tp_setattro */
1344 0, /* tp_as_buffer */
1345 Py_TPFLAGS_DEFAULT, /* tp_flags */
1346 kqueue_event_doc, /* tp_doc */
1347 0, /* tp_traverse */
1348 0, /* tp_clear */
1349 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1350 0, /* tp_weaklistoffset */
1351 0, /* tp_iter */
1352 0, /* tp_iternext */
1353 0, /* tp_methods */
1354 kqueue_event_members, /* tp_members */
1355 0, /* tp_getset */
1356 0, /* tp_base */
1357 0, /* tp_dict */
1358 0, /* tp_descr_get */
1359 0, /* tp_descr_set */
1360 0, /* tp_dictoffset */
1361 (initproc)kqueue_event_init, /* tp_init */
1362 0, /* tp_alloc */
1363 0, /* tp_new */
1364 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365};
1366
1367static PyObject *
1368kqueue_queue_err_closed(void)
1369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1371 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372}
1373
1374static int
1375kqueue_queue_internal_close(kqueue_queue_Object *self)
1376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 int save_errno = 0;
1378 if (self->kqfd >= 0) {
1379 int kqfd = self->kqfd;
1380 self->kqfd = -1;
1381 Py_BEGIN_ALLOW_THREADS
1382 if (close(kqfd) < 0)
1383 save_errno = errno;
1384 Py_END_ALLOW_THREADS
1385 }
1386 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001387}
1388
1389static PyObject *
1390newKqueue_Object(PyTypeObject *type, SOCKET fd)
1391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 kqueue_queue_Object *self;
1393 assert(type != NULL && type->tp_alloc != NULL);
1394 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1395 if (self == NULL) {
1396 return NULL;
1397 }
1398
1399 if (fd == -1) {
1400 Py_BEGIN_ALLOW_THREADS
1401 self->kqfd = kqueue();
1402 Py_END_ALLOW_THREADS
1403 }
1404 else {
1405 self->kqfd = fd;
1406 }
1407 if (self->kqfd < 0) {
1408 Py_DECREF(self);
1409 PyErr_SetFromErrno(PyExc_IOError);
1410 return NULL;
1411 }
1412 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001413}
1414
1415static PyObject *
1416kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1417{
1418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 if ((args != NULL && PyObject_Size(args)) ||
1420 (kwds != NULL && PyObject_Size(kwds))) {
1421 PyErr_SetString(PyExc_ValueError,
1422 "select.kqueue doesn't accept arguments");
1423 return NULL;
1424 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001427}
1428
1429static void
1430kqueue_queue_dealloc(kqueue_queue_Object *self)
1431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 kqueue_queue_internal_close(self);
1433 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001434}
1435
1436static PyObject*
1437kqueue_queue_close(kqueue_queue_Object *self)
1438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 errno = kqueue_queue_internal_close(self);
1440 if (errno < 0) {
1441 PyErr_SetFromErrno(PyExc_IOError);
1442 return NULL;
1443 }
1444 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001445}
1446
1447PyDoc_STRVAR(kqueue_queue_close_doc,
1448"close() -> None\n\
1449\n\
1450Close the kqueue control file descriptor. Further operations on the kqueue\n\
1451object will raise an exception.");
1452
1453static PyObject*
1454kqueue_queue_get_closed(kqueue_queue_Object *self)
1455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 if (self->kqfd < 0)
1457 Py_RETURN_TRUE;
1458 else
1459 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001460}
1461
1462static PyObject*
1463kqueue_queue_fileno(kqueue_queue_Object *self)
1464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 if (self->kqfd < 0)
1466 return kqueue_queue_err_closed();
1467 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001468}
1469
1470PyDoc_STRVAR(kqueue_queue_fileno_doc,
1471"fileno() -> int\n\
1472\n\
1473Return the kqueue control file descriptor.");
1474
1475static PyObject*
1476kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1481 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484}
1485
1486PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1487"fromfd(fd) -> kqueue\n\
1488\n\
1489Create a kqueue object from a given control fd.");
1490
1491static PyObject *
1492kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 int nevents = 0;
1495 int gotevents = 0;
1496 int nchanges = 0;
1497 int i = 0;
1498 PyObject *otimeout = NULL;
1499 PyObject *ch = NULL;
1500 PyObject *it = NULL, *ei = NULL;
1501 PyObject *result = NULL;
1502 struct kevent *evl = NULL;
1503 struct kevent *chl = NULL;
1504 struct timespec timeoutspec;
1505 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 if (self->kqfd < 0)
1508 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1511 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (nevents < 0) {
1514 PyErr_Format(PyExc_ValueError,
1515 "Length of eventlist must be 0 or positive, got %d",
1516 nevents);
1517 return NULL;
1518 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 if (otimeout == Py_None || otimeout == NULL) {
1521 ptimeoutspec = NULL;
1522 }
1523 else if (PyNumber_Check(otimeout)) {
1524 double timeout;
1525 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 timeout = PyFloat_AsDouble(otimeout);
1528 if (timeout == -1 && PyErr_Occurred())
1529 return NULL;
1530 if (timeout > (double)LONG_MAX) {
1531 PyErr_SetString(PyExc_OverflowError,
1532 "timeout period too long");
1533 return NULL;
1534 }
1535 if (timeout < 0) {
1536 PyErr_SetString(PyExc_ValueError,
1537 "timeout must be positive or None");
1538 return NULL;
1539 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 seconds = (long)timeout;
1542 timeout = timeout - (double)seconds;
1543 timeoutspec.tv_sec = seconds;
1544 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1545 ptimeoutspec = &timeoutspec;
1546 }
1547 else {
1548 PyErr_Format(PyExc_TypeError,
1549 "timeout argument must be an number "
1550 "or None, got %.200s",
1551 Py_TYPE(otimeout)->tp_name);
1552 return NULL;
1553 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 if (ch != NULL && ch != Py_None) {
1556 it = PyObject_GetIter(ch);
1557 if (it == NULL) {
1558 PyErr_SetString(PyExc_TypeError,
1559 "changelist is not iterable");
1560 return NULL;
1561 }
1562 nchanges = PyObject_Size(ch);
1563 if (nchanges < 0) {
1564 goto error;
1565 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 chl = PyMem_New(struct kevent, nchanges);
1568 if (chl == NULL) {
1569 PyErr_NoMemory();
1570 goto error;
1571 }
1572 i = 0;
1573 while ((ei = PyIter_Next(it)) != NULL) {
1574 if (!kqueue_event_Check(ei)) {
1575 Py_DECREF(ei);
1576 PyErr_SetString(PyExc_TypeError,
1577 "changelist must be an iterable of "
1578 "select.kevent objects");
1579 goto error;
1580 } else {
1581 chl[i++] = ((kqueue_event_Object *)ei)->e;
1582 }
1583 Py_DECREF(ei);
1584 }
1585 }
1586 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 /* event list */
1589 if (nevents) {
1590 evl = PyMem_New(struct kevent, nevents);
1591 if (evl == NULL) {
1592 PyErr_NoMemory();
1593 goto error;
1594 }
1595 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 Py_BEGIN_ALLOW_THREADS
1598 gotevents = kevent(self->kqfd, chl, nchanges,
1599 evl, nevents, ptimeoutspec);
1600 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 if (gotevents == -1) {
1603 PyErr_SetFromErrno(PyExc_OSError);
1604 goto error;
1605 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 result = PyList_New(gotevents);
1608 if (result == NULL) {
1609 goto error;
1610 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 for (i = 0; i < gotevents; i++) {
1613 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1616 if (ch == NULL) {
1617 goto error;
1618 }
1619 ch->e = evl[i];
1620 PyList_SET_ITEM(result, i, (PyObject *)ch);
1621 }
1622 PyMem_Free(chl);
1623 PyMem_Free(evl);
1624 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001625
1626 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 PyMem_Free(chl);
1628 PyMem_Free(evl);
1629 Py_XDECREF(result);
1630 Py_XDECREF(it);
1631 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632}
1633
1634PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001635"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001636\n\
1637Calls the kernel kevent function.\n\
1638- changelist must be a list of kevent objects describing the changes\n\
1639 to be made to the kernel's watch list or None.\n\
1640- max_events lets you specify the maximum number of events that the\n\
1641 kernel will return.\n\
1642- timeout is the maximum time to wait in seconds, or else None,\n\
1643 to wait forever. timeout accepts floats for smaller timeouts, too.");
1644
1645
1646static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1648 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1649 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1650 kqueue_queue_close_doc},
1651 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1652 kqueue_queue_fileno_doc},
1653 {"control", (PyCFunction)kqueue_queue_control,
1654 METH_VARARGS , kqueue_queue_control_doc},
1655 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001656};
1657
1658static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 {"closed", (getter)kqueue_queue_get_closed, NULL,
1660 "True if the kqueue handler is closed"},
1661 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001662};
1663
1664PyDoc_STRVAR(kqueue_queue_doc,
1665"Kqueue syscall wrapper.\n\
1666\n\
1667For example, to start watching a socket for input:\n\
1668>>> kq = kqueue()\n\
1669>>> sock = socket()\n\
1670>>> sock.connect((host, port))\n\
1671>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1672\n\
1673To wait one second for it to become writeable:\n\
1674>>> kq.control(None, 1, 1000)\n\
1675\n\
1676To stop listening:\n\
1677>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1678
1679static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 PyVarObject_HEAD_INIT(NULL, 0)
1681 "select.kqueue", /* tp_name */
1682 sizeof(kqueue_queue_Object), /* tp_basicsize */
1683 0, /* tp_itemsize */
1684 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1685 0, /* tp_print */
1686 0, /* tp_getattr */
1687 0, /* tp_setattr */
1688 0, /* tp_reserved */
1689 0, /* tp_repr */
1690 0, /* tp_as_number */
1691 0, /* tp_as_sequence */
1692 0, /* tp_as_mapping */
1693 0, /* tp_hash */
1694 0, /* tp_call */
1695 0, /* tp_str */
1696 0, /* tp_getattro */
1697 0, /* tp_setattro */
1698 0, /* tp_as_buffer */
1699 Py_TPFLAGS_DEFAULT, /* tp_flags */
1700 kqueue_queue_doc, /* tp_doc */
1701 0, /* tp_traverse */
1702 0, /* tp_clear */
1703 0, /* tp_richcompare */
1704 0, /* tp_weaklistoffset */
1705 0, /* tp_iter */
1706 0, /* tp_iternext */
1707 kqueue_queue_methods, /* tp_methods */
1708 0, /* tp_members */
1709 kqueue_queue_getsetlist, /* tp_getset */
1710 0, /* tp_base */
1711 0, /* tp_dict */
1712 0, /* tp_descr_get */
1713 0, /* tp_descr_set */
1714 0, /* tp_dictoffset */
1715 0, /* tp_init */
1716 0, /* tp_alloc */
1717 kqueue_queue_new, /* tp_new */
1718 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001719};
1720
1721#endif /* HAVE_KQUEUE */
1722/* ************************************************************************ */
1723
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001724PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001725"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1726\n\
1727Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001728The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001729rlist -- wait until ready for reading\n\
1730wlist -- wait until ready for writing\n\
1731xlist -- wait for an ``exceptional condition''\n\
1732If only one kind of condition is required, pass [] for the other lists.\n\
1733A file descriptor is either a socket or file object, or a small integer\n\
1734gotten from a fileno() method call on one of those.\n\
1735\n\
1736The optional 4th argument specifies a timeout in seconds; it may be\n\
1737a floating point number to specify fractions of seconds. If it is absent\n\
1738or None, the call will never time out.\n\
1739\n\
1740The return value is a tuple of three lists corresponding to the first three\n\
1741arguments; each contains the subset of the corresponding file descriptors\n\
1742that are ready.\n\
1743\n\
1744*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001745On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001746descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001747
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001748static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001750#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001752#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001754};
1755
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001756PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001757"This module supports asynchronous I/O on multiple file descriptors.\n\
1758\n\
1759*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001760On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001761
Martin v. Löwis1a214512008-06-11 05:26:20 +00001762
1763static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 PyModuleDef_HEAD_INIT,
1765 "select",
1766 module_doc,
1767 -1,
1768 select_methods,
1769 NULL,
1770 NULL,
1771 NULL,
1772 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001773};
1774
Mark Hammond62b1ab12002-07-23 06:31:15 +00001775PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001776PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 PyObject *m;
1779 m = PyModule_Create(&selectmodule);
1780 if (m == NULL)
1781 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 SelectError = PyErr_NewException("select.error", NULL, NULL);
1784 Py_INCREF(SelectError);
1785 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001786
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001787#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001788#ifdef HAVE_BROKEN_PIPE_BUF
1789#undef PIPE_BUF
1790#define PIPE_BUF 512
1791#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001793#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001794
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001795#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 if (select_have_broken_poll()) {
1798 if (PyObject_DelAttrString(m, "poll") == -1) {
1799 PyErr_Clear();
1800 }
1801 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001802#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001804#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 if (PyType_Ready(&poll_Type) < 0)
1806 return NULL;
1807 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1808 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1809 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1810 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1811 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1812 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001813
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001814#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001816#endif
1817#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001819#endif
1820#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001822#endif
1823#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001825#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001826#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001828#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001830#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831
1832#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1834 if (PyType_Ready(&pyEpoll_Type) < 0)
1835 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 Py_INCREF(&pyEpoll_Type);
1838 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1841 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1842 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1843 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1844 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1845 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001846#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 /* Kernel 2.6.2+ */
1848 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001849#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1851 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1852 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1853 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1854 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1855 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856#endif /* HAVE_EPOLL */
1857
1858#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 kqueue_event_Type.tp_new = PyType_GenericNew;
1860 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1861 if(PyType_Ready(&kqueue_event_Type) < 0)
1862 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 Py_INCREF(&kqueue_event_Type);
1865 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1868 if(PyType_Ready(&kqueue_queue_Type) < 0)
1869 return NULL;
1870 Py_INCREF(&kqueue_queue_Type);
1871 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1872
1873 /* event filters */
1874 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1875 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1876 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1877 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1878 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001879#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001881#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1883 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 /* event flags */
1886 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1887 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1888 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1889 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1890 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1891 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1894 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1897 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 /* READ WRITE filter flag */
1900 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 /* VNODE filter flags */
1903 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1907 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1908 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1909 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 /* PROC filter flags */
1912 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1915 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1916 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1919 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1920 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1921
1922 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001923#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1925 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1926 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001927#endif
1928
1929#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001931}