blob: 2452a651b17366d83e0405841022b240975293c1 [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 */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200113 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 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)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 o = fd2obj[j].obj;
164 fd2obj[j].obj = NULL;
165 /* transfer ownership */
166 if (PyList_SetItem(list, i, o) < 0)
167 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 i++;
170 }
171 }
172 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000173 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 Py_DECREF(list);
175 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000176}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177
Barry Warsawb44740f2001-08-16 16:52:59 +0000178#undef SELECT_USES_HEAP
179#if FD_SETSIZE > 1024
180#define SELECT_USES_HEAP
181#endif /* FD_SETSIZE > 1024 */
182
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000183static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000184select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000185{
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000188#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 /* XXX: All this should probably be implemented as follows:
190 * - find the highest descriptor we're interested in
191 * - add one
192 * - that's the size
193 * See: Stevens, APitUE, $12.5.1
194 */
195 pylist rfd2obj[FD_SETSIZE + 1];
196 pylist wfd2obj[FD_SETSIZE + 1];
197 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000198#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 PyObject *ifdlist, *ofdlist, *efdlist;
200 PyObject *ret = NULL;
201 PyObject *tout = Py_None;
202 fd_set ifdset, ofdset, efdset;
203 double timeout;
204 struct timeval tv, *tvp;
205 long seconds;
206 int imax, omax, emax, max;
207 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 /* convert arguments */
210 if (!PyArg_UnpackTuple(args, "select", 3, 4,
211 &ifdlist, &ofdlist, &efdlist, &tout))
212 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 if (tout == Py_None)
215 tvp = (struct timeval *)0;
216 else if (!PyNumber_Check(tout)) {
217 PyErr_SetString(PyExc_TypeError,
218 "timeout must be a float or None");
219 return NULL;
220 }
221 else {
222 timeout = PyFloat_AsDouble(tout);
223 if (timeout == -1 && PyErr_Occurred())
224 return NULL;
225 if (timeout > (double)LONG_MAX) {
226 PyErr_SetString(PyExc_OverflowError,
227 "timeout period too long");
228 return NULL;
229 }
230 seconds = (long)timeout;
231 timeout = timeout - (double)seconds;
232 tv.tv_sec = seconds;
233 tv.tv_usec = (long)(timeout * 1E6);
234 tvp = &tv;
235 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000236
Guido van Rossumed233a51992-06-23 09:07:03 +0000237
Barry Warsawb44740f2001-08-16 16:52:59 +0000238#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 /* Allocate memory for the lists */
240 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
241 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
242 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
243 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
244 if (rfd2obj) PyMem_DEL(rfd2obj);
245 if (wfd2obj) PyMem_DEL(wfd2obj);
246 if (efd2obj) PyMem_DEL(efd2obj);
247 return PyErr_NoMemory();
248 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000249#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 /* Convert sequences to fd_sets, and get maximum fd number
251 * propagates the Python exception set in seq2set()
252 */
253 rfd2obj[0].sentinel = -1;
254 wfd2obj[0].sentinel = -1;
255 efd2obj[0].sentinel = -1;
256 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
257 goto finally;
258 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
259 goto finally;
260 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
261 goto finally;
262 max = imax;
263 if (omax > max) max = omax;
264 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 Py_BEGIN_ALLOW_THREADS
267 n = select(max, &ifdset, &ofdset, &efdset, tvp);
268 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000269
Thomas Heller106f4c72002-09-24 16:51:00 +0000270#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 if (n == SOCKET_ERROR) {
272 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
273 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000274#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 if (n < 0) {
276 PyErr_SetFromErrno(SelectError);
277 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000278#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 else {
280 /* any of these three calls can raise an exception. it's more
281 convenient to test for this after all three calls... but
282 is that acceptable?
283 */
284 ifdlist = set2list(&ifdset, rfd2obj);
285 ofdlist = set2list(&ofdset, wfd2obj);
286 efdlist = set2list(&efdset, efd2obj);
287 if (PyErr_Occurred())
288 ret = NULL;
289 else
290 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 Py_DECREF(ifdlist);
293 Py_DECREF(ofdlist);
294 Py_DECREF(efdlist);
295 }
296
Barry Warsawc1cb3601996-12-12 22:16:21 +0000297 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 reap_obj(rfd2obj);
299 reap_obj(wfd2obj);
300 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000301#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 PyMem_DEL(rfd2obj);
303 PyMem_DEL(wfd2obj);
304 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000305#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000307}
308
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000309#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000311 * poll() support
312 */
313
314typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 PyObject_HEAD
316 PyObject *dict;
317 int ufd_uptodate;
318 int ufd_len;
319 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000320} pollObject;
321
Jeremy Hylton938ace62002-07-17 16:30:39 +0000322static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000325 contained within a pollObject. Return 1 on success, 0 on an error.
326*/
327
328static int
329update_ufd_array(pollObject *self)
330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 Py_ssize_t i, pos;
332 PyObject *key, *value;
333 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 self->ufd_len = PyDict_Size(self->dict);
336 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
337 if (self->ufds == NULL) {
338 self->ufds = old_ufds;
339 PyErr_NoMemory();
340 return 0;
341 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 i = pos = 0;
344 while (PyDict_Next(self->dict, &pos, &key, &value)) {
345 self->ufds[i].fd = PyLong_AsLong(key);
346 self->ufds[i].events = (short)PyLong_AsLong(value);
347 i++;
348 }
349 self->ufd_uptodate = 1;
350 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351}
352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000353PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000354"register(fd [, eventmask] ) -> None\n\n\
355Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000356fd -- either an integer, or an object with a fileno() method returning an\n\
357 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000358events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359
360static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 PyObject *o, *key, *value;
364 int fd, events = POLLIN | POLLPRI | POLLOUT;
365 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
368 return NULL;
369 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 fd = PyObject_AsFileDescriptor(o);
372 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 /* Add entry to the internal dictionary: the key is the
375 file descriptor, and the value is the event mask. */
376 key = PyLong_FromLong(fd);
377 if (key == NULL)
378 return NULL;
379 value = PyLong_FromLong(events);
380 if (value == NULL) {
381 Py_DECREF(key);
382 return NULL;
383 }
384 err = PyDict_SetItem(self->dict, key, value);
385 Py_DECREF(key);
386 Py_DECREF(value);
387 if (err < 0)
388 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 self->ufd_uptodate = 0;
391
392 Py_INCREF(Py_None);
393 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000394}
395
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000396PyDoc_STRVAR(poll_modify_doc,
397"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000398Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000399fd -- either an integer, or an object with a fileno() method returning an\n\
400 int.\n\
401events -- an optional bitmask describing the type of events to check for");
402
403static PyObject *
404poll_modify(pollObject *self, PyObject *args)
405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 PyObject *o, *key, *value;
407 int fd, events;
408 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
411 return NULL;
412 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 fd = PyObject_AsFileDescriptor(o);
415 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 /* Modify registered fd */
418 key = PyLong_FromLong(fd);
419 if (key == NULL)
420 return NULL;
421 if (PyDict_GetItem(self->dict, key) == NULL) {
422 errno = ENOENT;
423 PyErr_SetFromErrno(PyExc_IOError);
424 return NULL;
425 }
426 value = PyLong_FromLong(events);
427 if (value == NULL) {
428 Py_DECREF(key);
429 return NULL;
430 }
431 err = PyDict_SetItem(self->dict, key, value);
432 Py_DECREF(key);
433 Py_DECREF(value);
434 if (err < 0)
435 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 self->ufd_uptodate = 0;
438
439 Py_INCREF(Py_None);
440 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000441}
442
443
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000444PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000445"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000446Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000447
448static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 PyObject *key;
452 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 fd = PyObject_AsFileDescriptor( o );
455 if (fd == -1)
456 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 /* Check whether the fd is already in the array */
459 key = PyLong_FromLong(fd);
460 if (key == NULL)
461 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 if (PyDict_DelItem(self->dict, key) == -1) {
464 Py_DECREF(key);
465 /* This will simply raise the KeyError set by PyDict_DelItem
466 if the file descriptor isn't registered. */
467 return NULL;
468 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 Py_DECREF(key);
471 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 Py_INCREF(Py_None);
474 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475}
476
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000477PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000478"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
479Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000480any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000481
482static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 PyObject *result_list = NULL, *tout = NULL;
486 int timeout = 0, poll_result, i, j;
487 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
490 return NULL;
491 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 /* Check values for timeout */
494 if (tout == NULL || tout == Py_None)
495 timeout = -1;
496 else if (!PyNumber_Check(tout)) {
497 PyErr_SetString(PyExc_TypeError,
498 "timeout must be an integer or None");
499 return NULL;
500 }
501 else {
502 tout = PyNumber_Long(tout);
503 if (!tout)
504 return NULL;
505 timeout = PyLong_AsLong(tout);
506 Py_DECREF(tout);
507 if (timeout == -1 && PyErr_Occurred())
508 return NULL;
509 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 /* Ensure the ufd array is up to date */
512 if (!self->ufd_uptodate)
513 if (update_ufd_array(self) == 0)
514 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 /* call poll() */
517 Py_BEGIN_ALLOW_THREADS
518 poll_result = poll(self->ufds, self->ufd_len, timeout);
519 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 if (poll_result < 0) {
522 PyErr_SetFromErrno(SelectError);
523 return NULL;
524 }
525
526 /* build the result list */
527
528 result_list = PyList_New(poll_result);
529 if (!result_list)
530 return NULL;
531 else {
532 for (i = 0, j = 0; j < poll_result; j++) {
533 /* skip to the next fired descriptor */
534 while (!self->ufds[i].revents) {
535 i++;
536 }
537 /* if we hit a NULL return, set value to NULL
538 and break out of loop; code at end will
539 clean up result_list */
540 value = PyTuple_New(2);
541 if (value == NULL)
542 goto error;
543 num = PyLong_FromLong(self->ufds[i].fd);
544 if (num == NULL) {
545 Py_DECREF(value);
546 goto error;
547 }
548 PyTuple_SET_ITEM(value, 0, num);
549
550 /* The &0xffff is a workaround for AIX. 'revents'
551 is a 16-bit short, and IBM assigned POLLNVAL
552 to be 0x8000, so the conversion to int results
553 in a negative number. See SF bug #923315. */
554 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
555 if (num == NULL) {
556 Py_DECREF(value);
557 goto error;
558 }
559 PyTuple_SET_ITEM(value, 1, num);
560 if ((PyList_SetItem(result_list, j, value)) == -1) {
561 Py_DECREF(value);
562 goto error;
563 }
564 i++;
565 }
566 }
567 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000568
569 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 Py_DECREF(result_list);
571 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000572}
573
574static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 {"register", (PyCFunction)poll_register,
576 METH_VARARGS, poll_register_doc},
577 {"modify", (PyCFunction)poll_modify,
578 METH_VARARGS, poll_modify_doc},
579 {"unregister", (PyCFunction)poll_unregister,
580 METH_O, poll_unregister_doc},
581 {"poll", (PyCFunction)poll_poll,
582 METH_VARARGS, poll_poll_doc},
583 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584};
585
586static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000587newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000588{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 pollObject *self;
590 self = PyObject_New(pollObject, &poll_Type);
591 if (self == NULL)
592 return NULL;
593 /* ufd_uptodate is a Boolean, denoting whether the
594 array pointed to by ufds matches the contents of the dictionary. */
595 self->ufd_uptodate = 0;
596 self->ufds = NULL;
597 self->dict = PyDict_New();
598 if (self->dict == NULL) {
599 Py_DECREF(self);
600 return NULL;
601 }
602 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000603}
604
605static void
606poll_dealloc(pollObject *self)
607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 if (self->ufds != NULL)
609 PyMem_DEL(self->ufds);
610 Py_XDECREF(self->dict);
611 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000612}
613
Tim Peters0c322792002-07-17 16:49:03 +0000614static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 /* The ob_type field must be initialized in the module init function
616 * to be portable to Windows without using C++. */
617 PyVarObject_HEAD_INIT(NULL, 0)
618 "select.poll", /*tp_name*/
619 sizeof(pollObject), /*tp_basicsize*/
620 0, /*tp_itemsize*/
621 /* methods */
622 (destructor)poll_dealloc, /*tp_dealloc*/
623 0, /*tp_print*/
624 0, /*tp_getattr*/
625 0, /*tp_setattr*/
626 0, /*tp_reserved*/
627 0, /*tp_repr*/
628 0, /*tp_as_number*/
629 0, /*tp_as_sequence*/
630 0, /*tp_as_mapping*/
631 0, /*tp_hash*/
632 0, /*tp_call*/
633 0, /*tp_str*/
634 0, /*tp_getattro*/
635 0, /*tp_setattro*/
636 0, /*tp_as_buffer*/
637 Py_TPFLAGS_DEFAULT, /*tp_flags*/
638 0, /*tp_doc*/
639 0, /*tp_traverse*/
640 0, /*tp_clear*/
641 0, /*tp_richcompare*/
642 0, /*tp_weaklistoffset*/
643 0, /*tp_iter*/
644 0, /*tp_iternext*/
645 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000646};
647
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000648PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000649"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000650unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000651
652static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000653select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000656}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657
658#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000660 * On some systems poll() sets errno on invalid file descriptors. We test
661 * for this at runtime because this bug may be fixed or introduced between
662 * OS releases.
663 */
664static int select_have_broken_poll(void)
665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 int poll_test;
667 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 /* Create a file descriptor to make invalid */
672 if (pipe(filedes) < 0) {
673 return 1;
674 }
675 poll_struct.fd = filedes[0];
676 close(filedes[0]);
677 close(filedes[1]);
678 poll_test = poll(&poll_struct, 1, 0);
679 if (poll_test < 0) {
680 return 1;
681 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
682 return 1;
683 }
684 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000685}
686#endif /* __APPLE__ */
687
688#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000689
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000690#ifdef HAVE_EPOLL
691/* **************************************************************************
692 * epoll interface for Linux 2.6
693 *
694 * Written by Christian Heimes
695 * Inspired by Twisted's _epoll.pyx and select.poll()
696 */
697
698#ifdef HAVE_SYS_EPOLL_H
699#include <sys/epoll.h>
700#endif
701
702typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 PyObject_HEAD
704 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000705} pyEpoll_Object;
706
707static PyTypeObject pyEpoll_Type;
708#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
709
710static PyObject *
711pyepoll_err_closed(void)
712{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
714 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000715}
716
717static int
718pyepoll_internal_close(pyEpoll_Object *self)
719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 int save_errno = 0;
721 if (self->epfd >= 0) {
722 int epfd = self->epfd;
723 self->epfd = -1;
724 Py_BEGIN_ALLOW_THREADS
725 if (close(epfd) < 0)
726 save_errno = errno;
727 Py_END_ALLOW_THREADS
728 }
729 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000730}
731
732static PyObject *
733newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000736
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 if (sizehint == -1) {
738 sizehint = FD_SETSIZE-1;
739 }
740 else if (sizehint < 1) {
741 PyErr_Format(PyExc_ValueError,
742 "sizehint must be greater zero, got %d",
743 sizehint);
744 return NULL;
745 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 assert(type != NULL && type->tp_alloc != NULL);
748 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
749 if (self == NULL)
750 return NULL;
751
752 if (fd == -1) {
753 Py_BEGIN_ALLOW_THREADS
754 self->epfd = epoll_create(sizehint);
755 Py_END_ALLOW_THREADS
756 }
757 else {
758 self->epfd = fd;
759 }
760 if (self->epfd < 0) {
761 Py_DECREF(self);
762 PyErr_SetFromErrno(PyExc_IOError);
763 return NULL;
764 }
765 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000766}
767
768
769static PyObject *
770pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 int sizehint = -1;
773 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
776 &sizehint))
777 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000780}
781
782
783static void
784pyepoll_dealloc(pyEpoll_Object *self)
785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 (void)pyepoll_internal_close(self);
787 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000788}
789
790static PyObject*
791pyepoll_close(pyEpoll_Object *self)
792{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 errno = pyepoll_internal_close(self);
794 if (errno < 0) {
795 PyErr_SetFromErrno(PyExc_IOError);
796 return NULL;
797 }
798 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000799}
800
801PyDoc_STRVAR(pyepoll_close_doc,
802"close() -> None\n\
803\n\
804Close the epoll control file descriptor. Further operations on the epoll\n\
805object will raise an exception.");
806
807static PyObject*
808pyepoll_get_closed(pyEpoll_Object *self)
809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 if (self->epfd < 0)
811 Py_RETURN_TRUE;
812 else
813 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000814}
815
816static PyObject*
817pyepoll_fileno(pyEpoll_Object *self)
818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 if (self->epfd < 0)
820 return pyepoll_err_closed();
821 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000822}
823
824PyDoc_STRVAR(pyepoll_fileno_doc,
825"fileno() -> int\n\
826\n\
827Return the epoll control file descriptor.");
828
829static PyObject*
830pyepoll_fromfd(PyObject *cls, PyObject *args)
831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
835 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000838}
839
840PyDoc_STRVAR(pyepoll_fromfd_doc,
841"fromfd(fd) -> epoll\n\
842\n\
843Create an epoll object from a given control fd.");
844
845static PyObject *
846pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 struct epoll_event ev;
849 int result;
850 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 if (epfd < 0)
853 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 fd = PyObject_AsFileDescriptor(pfd);
856 if (fd == -1) {
857 return NULL;
858 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 switch(op) {
861 case EPOLL_CTL_ADD:
862 case EPOLL_CTL_MOD:
863 ev.events = events;
864 ev.data.fd = fd;
865 Py_BEGIN_ALLOW_THREADS
866 result = epoll_ctl(epfd, op, fd, &ev);
867 Py_END_ALLOW_THREADS
868 break;
869 case EPOLL_CTL_DEL:
870 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
871 * operation required a non-NULL pointer in event, even
872 * though this argument is ignored. */
873 Py_BEGIN_ALLOW_THREADS
874 result = epoll_ctl(epfd, op, fd, &ev);
875 if (errno == EBADF) {
876 /* fd already closed */
877 result = 0;
878 errno = 0;
879 }
880 Py_END_ALLOW_THREADS
881 break;
882 default:
883 result = -1;
884 errno = EINVAL;
885 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 if (result < 0) {
888 PyErr_SetFromErrno(PyExc_IOError);
889 return NULL;
890 }
891 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000892}
893
894static PyObject *
895pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 PyObject *pfd;
898 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
899 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
902 &pfd, &events)) {
903 return NULL;
904 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000907}
908
909PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000910"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000911\n\
Senthil Kumaran7d80bd12011-06-26 23:48:23 -0700912Registers a new fd or raises an IOError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000913fd is the target file descriptor of the operation.\n\
914events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000915is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
916\n\
917The epoll interface supports all file descriptors that support poll.");
918
919static PyObject *
920pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 PyObject *pfd;
923 unsigned int events;
924 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
927 &pfd, &events)) {
928 return NULL;
929 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000932}
933
934PyDoc_STRVAR(pyepoll_modify_doc,
935"modify(fd, eventmask) -> None\n\
936\n\
937fd is the target file descriptor of the operation\n\
938events is a bit set composed of the various EPOLL constants");
939
940static PyObject *
941pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 PyObject *pfd;
944 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
947 &pfd)) {
948 return NULL;
949 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000952}
953
954PyDoc_STRVAR(pyepoll_unregister_doc,
955"unregister(fd) -> None\n\
956\n\
957fd is the target file descriptor of the operation.");
958
959static PyObject *
960pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 double dtimeout = -1.;
963 int timeout;
964 int maxevents = -1;
965 int nfds, i;
966 PyObject *elist = NULL, *etuple = NULL;
967 struct epoll_event *evs = NULL;
968 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 if (self->epfd < 0)
971 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
974 &dtimeout, &maxevents)) {
975 return NULL;
976 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 if (dtimeout < 0) {
979 timeout = -1;
980 }
981 else if (dtimeout * 1000.0 > INT_MAX) {
982 PyErr_SetString(PyExc_OverflowError,
983 "timeout is too large");
984 return NULL;
985 }
986 else {
987 timeout = (int)(dtimeout * 1000.0);
988 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 if (maxevents == -1) {
991 maxevents = FD_SETSIZE-1;
992 }
993 else if (maxevents < 1) {
994 PyErr_Format(PyExc_ValueError,
995 "maxevents must be greater than 0, got %d",
996 maxevents);
997 return NULL;
998 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 evs = PyMem_New(struct epoll_event, maxevents);
1001 if (evs == NULL) {
1002 Py_DECREF(self);
1003 PyErr_NoMemory();
1004 return NULL;
1005 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 Py_BEGIN_ALLOW_THREADS
1008 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1009 Py_END_ALLOW_THREADS
1010 if (nfds < 0) {
1011 PyErr_SetFromErrno(PyExc_IOError);
1012 goto error;
1013 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 elist = PyList_New(nfds);
1016 if (elist == NULL) {
1017 goto error;
1018 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 for (i = 0; i < nfds; i++) {
1021 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1022 if (etuple == NULL) {
1023 Py_CLEAR(elist);
1024 goto error;
1025 }
1026 PyList_SET_ITEM(elist, i, etuple);
1027 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001028
Christian Heimesf6cd9672008-03-26 13:45:42 +00001029 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 PyMem_Free(evs);
1031 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001032}
1033
1034PyDoc_STRVAR(pyepoll_poll_doc,
1035"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1036\n\
1037Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1038in seconds (as float). -1 makes poll wait indefinitely.\n\
1039Up to maxevents are returned to the caller.");
1040
1041static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 {"fromfd", (PyCFunction)pyepoll_fromfd,
1043 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1044 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1045 pyepoll_close_doc},
1046 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1047 pyepoll_fileno_doc},
1048 {"modify", (PyCFunction)pyepoll_modify,
1049 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1050 {"register", (PyCFunction)pyepoll_register,
1051 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1052 {"unregister", (PyCFunction)pyepoll_unregister,
1053 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1054 {"poll", (PyCFunction)pyepoll_poll,
1055 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1056 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001057};
1058
1059static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 {"closed", (getter)pyepoll_get_closed, NULL,
1061 "True if the epoll handler is closed"},
1062 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001063};
1064
1065PyDoc_STRVAR(pyepoll_doc,
1066"select.epoll([sizehint=-1])\n\
1067\n\
1068Returns an epolling object\n\
1069\n\
1070sizehint must be a positive integer or -1 for the default size. The\n\
1071sizehint is used to optimize internal data structures. It doesn't limit\n\
1072the maximum number of monitored events.");
1073
1074static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 PyVarObject_HEAD_INIT(NULL, 0)
1076 "select.epoll", /* tp_name */
1077 sizeof(pyEpoll_Object), /* tp_basicsize */
1078 0, /* tp_itemsize */
1079 (destructor)pyepoll_dealloc, /* tp_dealloc */
1080 0, /* tp_print */
1081 0, /* tp_getattr */
1082 0, /* tp_setattr */
1083 0, /* tp_reserved */
1084 0, /* tp_repr */
1085 0, /* tp_as_number */
1086 0, /* tp_as_sequence */
1087 0, /* tp_as_mapping */
1088 0, /* tp_hash */
1089 0, /* tp_call */
1090 0, /* tp_str */
1091 PyObject_GenericGetAttr, /* tp_getattro */
1092 0, /* tp_setattro */
1093 0, /* tp_as_buffer */
1094 Py_TPFLAGS_DEFAULT, /* tp_flags */
1095 pyepoll_doc, /* tp_doc */
1096 0, /* tp_traverse */
1097 0, /* tp_clear */
1098 0, /* tp_richcompare */
1099 0, /* tp_weaklistoffset */
1100 0, /* tp_iter */
1101 0, /* tp_iternext */
1102 pyepoll_methods, /* tp_methods */
1103 0, /* tp_members */
1104 pyepoll_getsetlist, /* tp_getset */
1105 0, /* tp_base */
1106 0, /* tp_dict */
1107 0, /* tp_descr_get */
1108 0, /* tp_descr_set */
1109 0, /* tp_dictoffset */
1110 0, /* tp_init */
1111 0, /* tp_alloc */
1112 pyepoll_new, /* tp_new */
1113 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001114};
1115
1116#endif /* HAVE_EPOLL */
1117
1118#ifdef HAVE_KQUEUE
1119/* **************************************************************************
1120 * kqueue interface for BSD
1121 *
1122 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1123 * All rights reserved.
1124 *
1125 * Redistribution and use in source and binary forms, with or without
1126 * modification, are permitted provided that the following conditions
1127 * are met:
1128 * 1. Redistributions of source code must retain the above copyright
1129 * notice, this list of conditions and the following disclaimer.
1130 * 2. Redistributions in binary form must reproduce the above copyright
1131 * notice, this list of conditions and the following disclaimer in the
1132 * documentation and/or other materials provided with the distribution.
1133 *
1134 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1135 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1136 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1137 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1138 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1139 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1140 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1141 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1142 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1143 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1144 * SUCH DAMAGE.
1145 */
1146
1147#ifdef HAVE_SYS_EVENT_H
1148#include <sys/event.h>
1149#endif
1150
1151PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001152"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001153\n\
1154This object is the equivalent of the struct kevent for the C API.\n\
1155\n\
1156See the kqueue manpage for more detailed information about the meaning\n\
1157of the arguments.\n\
1158\n\
1159One minor note: while you might hope that udata could store a\n\
1160reference to a python object, it cannot, because it is impossible to\n\
1161keep a proper reference count of the object once it's passed into the\n\
1162kernel. Therefore, I have restricted it to only storing an integer. I\n\
1163recommend ignoring it and simply using the 'ident' field to key off\n\
1164of. You could also set up a dictionary on the python side to store a\n\
1165udata->object mapping.");
1166
1167typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 PyObject_HEAD
1169 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001170} kqueue_event_Object;
1171
1172static PyTypeObject kqueue_event_Type;
1173
1174#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1175
1176typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 PyObject_HEAD
1178 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001179} kqueue_queue_Object;
1180
1181static PyTypeObject kqueue_queue_Type;
1182
1183#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1184
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001185#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1186# error uintptr_t does not match void *!
1187#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1188# define T_UINTPTRT T_ULONGLONG
1189# define T_INTPTRT T_LONGLONG
1190# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1191# define UINTPTRT_FMT_UNIT "K"
1192# define INTPTRT_FMT_UNIT "L"
1193#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1194# define T_UINTPTRT T_ULONG
1195# define T_INTPTRT T_LONG
1196# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1197# define UINTPTRT_FMT_UNIT "k"
1198# define INTPTRT_FMT_UNIT "l"
1199#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1200# define T_UINTPTRT T_UINT
1201# define T_INTPTRT T_INT
1202# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1203# define UINTPTRT_FMT_UNIT "I"
1204# define INTPTRT_FMT_UNIT "i"
1205#else
1206# error uintptr_t does not match int, long, or long long!
1207#endif
1208
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001209/* Unfortunately, we can't store python objects in udata, because
1210 * kevents in the kernel can be removed without warning, which would
1211 * forever lose the refcount on the object stored with it.
1212 */
1213
1214#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1215static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1217 {"filter", T_SHORT, KQ_OFF(e.filter)},
1218 {"flags", T_USHORT, KQ_OFF(e.flags)},
1219 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1220 {"data", T_INTPTRT, KQ_OFF(e.data)},
1221 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1222 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001223};
1224#undef KQ_OFF
1225
1226static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001227
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001228kqueue_event_repr(kqueue_event_Object *s)
1229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 char buf[1024];
1231 PyOS_snprintf(
1232 buf, sizeof(buf),
1233 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1234 "data=0x%zd udata=%p>",
1235 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1236 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1237 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001238}
1239
1240static int
1241kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 PyObject *pfd;
1244 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1245 "data", "udata", NULL};
1246 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1251 &pfd, &(self->e.filter), &(self->e.flags),
1252 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1253 return -1;
1254 }
1255
1256 if (PyLong_Check(pfd)) {
1257 self->e.ident = PyLong_AsUintptr_t(pfd);
1258 }
1259 else {
1260 self->e.ident = PyObject_AsFileDescriptor(pfd);
1261 }
1262 if (PyErr_Occurred()) {
1263 return -1;
1264 }
1265 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001266}
1267
1268static PyObject *
1269kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 if (!kqueue_event_Check(o)) {
1275 if (op == Py_EQ || op == Py_NE) {
1276 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1277 Py_INCREF(res);
1278 return res;
1279 }
1280 PyErr_Format(PyExc_TypeError,
1281 "can't compare %.200s to %.200s",
1282 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1283 return NULL;
1284 }
1285 if (((result = s->e.ident - o->e.ident) == 0) &&
1286 ((result = s->e.filter - o->e.filter) == 0) &&
1287 ((result = s->e.flags - o->e.flags) == 0) &&
1288 ((result = s->e.fflags - o->e.fflags) == 0) &&
1289 ((result = s->e.data - o->e.data) == 0) &&
1290 ((result = s->e.udata - o->e.udata) == 0)
1291 ) {
1292 result = 0;
1293 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 switch (op) {
1296 case Py_EQ:
1297 result = (result == 0);
1298 break;
1299 case Py_NE:
1300 result = (result != 0);
1301 break;
1302 case Py_LE:
1303 result = (result <= 0);
1304 break;
1305 case Py_GE:
1306 result = (result >= 0);
1307 break;
1308 case Py_LT:
1309 result = (result < 0);
1310 break;
1311 case Py_GT:
1312 result = (result > 0);
1313 break;
1314 }
1315 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001316}
1317
1318static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 PyVarObject_HEAD_INIT(NULL, 0)
1320 "select.kevent", /* tp_name */
1321 sizeof(kqueue_event_Object), /* tp_basicsize */
1322 0, /* tp_itemsize */
1323 0, /* tp_dealloc */
1324 0, /* tp_print */
1325 0, /* tp_getattr */
1326 0, /* tp_setattr */
1327 0, /* tp_reserved */
1328 (reprfunc)kqueue_event_repr, /* tp_repr */
1329 0, /* tp_as_number */
1330 0, /* tp_as_sequence */
1331 0, /* tp_as_mapping */
1332 0, /* tp_hash */
1333 0, /* tp_call */
1334 0, /* tp_str */
1335 0, /* tp_getattro */
1336 0, /* tp_setattro */
1337 0, /* tp_as_buffer */
1338 Py_TPFLAGS_DEFAULT, /* tp_flags */
1339 kqueue_event_doc, /* tp_doc */
1340 0, /* tp_traverse */
1341 0, /* tp_clear */
1342 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1343 0, /* tp_weaklistoffset */
1344 0, /* tp_iter */
1345 0, /* tp_iternext */
1346 0, /* tp_methods */
1347 kqueue_event_members, /* tp_members */
1348 0, /* tp_getset */
1349 0, /* tp_base */
1350 0, /* tp_dict */
1351 0, /* tp_descr_get */
1352 0, /* tp_descr_set */
1353 0, /* tp_dictoffset */
1354 (initproc)kqueue_event_init, /* tp_init */
1355 0, /* tp_alloc */
1356 0, /* tp_new */
1357 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001358};
1359
1360static PyObject *
1361kqueue_queue_err_closed(void)
1362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1364 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365}
1366
1367static int
1368kqueue_queue_internal_close(kqueue_queue_Object *self)
1369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 int save_errno = 0;
1371 if (self->kqfd >= 0) {
1372 int kqfd = self->kqfd;
1373 self->kqfd = -1;
1374 Py_BEGIN_ALLOW_THREADS
1375 if (close(kqfd) < 0)
1376 save_errno = errno;
1377 Py_END_ALLOW_THREADS
1378 }
1379 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380}
1381
1382static PyObject *
1383newKqueue_Object(PyTypeObject *type, SOCKET fd)
1384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 kqueue_queue_Object *self;
1386 assert(type != NULL && type->tp_alloc != NULL);
1387 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1388 if (self == NULL) {
1389 return NULL;
1390 }
1391
1392 if (fd == -1) {
1393 Py_BEGIN_ALLOW_THREADS
1394 self->kqfd = kqueue();
1395 Py_END_ALLOW_THREADS
1396 }
1397 else {
1398 self->kqfd = fd;
1399 }
1400 if (self->kqfd < 0) {
1401 Py_DECREF(self);
1402 PyErr_SetFromErrno(PyExc_IOError);
1403 return NULL;
1404 }
1405 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001406}
1407
1408static PyObject *
1409kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1410{
1411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 if ((args != NULL && PyObject_Size(args)) ||
1413 (kwds != NULL && PyObject_Size(kwds))) {
1414 PyErr_SetString(PyExc_ValueError,
1415 "select.kqueue doesn't accept arguments");
1416 return NULL;
1417 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001420}
1421
1422static void
1423kqueue_queue_dealloc(kqueue_queue_Object *self)
1424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 kqueue_queue_internal_close(self);
1426 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001427}
1428
1429static PyObject*
1430kqueue_queue_close(kqueue_queue_Object *self)
1431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 errno = kqueue_queue_internal_close(self);
1433 if (errno < 0) {
1434 PyErr_SetFromErrno(PyExc_IOError);
1435 return NULL;
1436 }
1437 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001438}
1439
1440PyDoc_STRVAR(kqueue_queue_close_doc,
1441"close() -> None\n\
1442\n\
1443Close the kqueue control file descriptor. Further operations on the kqueue\n\
1444object will raise an exception.");
1445
1446static PyObject*
1447kqueue_queue_get_closed(kqueue_queue_Object *self)
1448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 if (self->kqfd < 0)
1450 Py_RETURN_TRUE;
1451 else
1452 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001453}
1454
1455static PyObject*
1456kqueue_queue_fileno(kqueue_queue_Object *self)
1457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 if (self->kqfd < 0)
1459 return kqueue_queue_err_closed();
1460 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461}
1462
1463PyDoc_STRVAR(kqueue_queue_fileno_doc,
1464"fileno() -> int\n\
1465\n\
1466Return the kqueue control file descriptor.");
1467
1468static PyObject*
1469kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1474 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001477}
1478
1479PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1480"fromfd(fd) -> kqueue\n\
1481\n\
1482Create a kqueue object from a given control fd.");
1483
1484static PyObject *
1485kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 int nevents = 0;
1488 int gotevents = 0;
1489 int nchanges = 0;
1490 int i = 0;
1491 PyObject *otimeout = NULL;
1492 PyObject *ch = NULL;
1493 PyObject *it = NULL, *ei = NULL;
1494 PyObject *result = NULL;
1495 struct kevent *evl = NULL;
1496 struct kevent *chl = NULL;
1497 struct timespec timeoutspec;
1498 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 if (self->kqfd < 0)
1501 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1504 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 if (nevents < 0) {
1507 PyErr_Format(PyExc_ValueError,
1508 "Length of eventlist must be 0 or positive, got %d",
1509 nevents);
1510 return NULL;
1511 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (otimeout == Py_None || otimeout == NULL) {
1514 ptimeoutspec = NULL;
1515 }
1516 else if (PyNumber_Check(otimeout)) {
1517 double timeout;
1518 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 timeout = PyFloat_AsDouble(otimeout);
1521 if (timeout == -1 && PyErr_Occurred())
1522 return NULL;
1523 if (timeout > (double)LONG_MAX) {
1524 PyErr_SetString(PyExc_OverflowError,
1525 "timeout period too long");
1526 return NULL;
1527 }
1528 if (timeout < 0) {
1529 PyErr_SetString(PyExc_ValueError,
1530 "timeout must be positive or None");
1531 return NULL;
1532 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 seconds = (long)timeout;
1535 timeout = timeout - (double)seconds;
1536 timeoutspec.tv_sec = seconds;
1537 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1538 ptimeoutspec = &timeoutspec;
1539 }
1540 else {
1541 PyErr_Format(PyExc_TypeError,
1542 "timeout argument must be an number "
1543 "or None, got %.200s",
1544 Py_TYPE(otimeout)->tp_name);
1545 return NULL;
1546 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (ch != NULL && ch != Py_None) {
1549 it = PyObject_GetIter(ch);
1550 if (it == NULL) {
1551 PyErr_SetString(PyExc_TypeError,
1552 "changelist is not iterable");
1553 return NULL;
1554 }
1555 nchanges = PyObject_Size(ch);
1556 if (nchanges < 0) {
1557 goto error;
1558 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 chl = PyMem_New(struct kevent, nchanges);
1561 if (chl == NULL) {
1562 PyErr_NoMemory();
1563 goto error;
1564 }
1565 i = 0;
1566 while ((ei = PyIter_Next(it)) != NULL) {
1567 if (!kqueue_event_Check(ei)) {
1568 Py_DECREF(ei);
1569 PyErr_SetString(PyExc_TypeError,
1570 "changelist must be an iterable of "
1571 "select.kevent objects");
1572 goto error;
1573 } else {
1574 chl[i++] = ((kqueue_event_Object *)ei)->e;
1575 }
1576 Py_DECREF(ei);
1577 }
1578 }
1579 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 /* event list */
1582 if (nevents) {
1583 evl = PyMem_New(struct kevent, nevents);
1584 if (evl == NULL) {
1585 PyErr_NoMemory();
1586 goto error;
1587 }
1588 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 Py_BEGIN_ALLOW_THREADS
1591 gotevents = kevent(self->kqfd, chl, nchanges,
1592 evl, nevents, ptimeoutspec);
1593 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (gotevents == -1) {
1596 PyErr_SetFromErrno(PyExc_OSError);
1597 goto error;
1598 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 result = PyList_New(gotevents);
1601 if (result == NULL) {
1602 goto error;
1603 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 for (i = 0; i < gotevents; i++) {
1606 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1609 if (ch == NULL) {
1610 goto error;
1611 }
1612 ch->e = evl[i];
1613 PyList_SET_ITEM(result, i, (PyObject *)ch);
1614 }
1615 PyMem_Free(chl);
1616 PyMem_Free(evl);
1617 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001618
1619 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 PyMem_Free(chl);
1621 PyMem_Free(evl);
1622 Py_XDECREF(result);
1623 Py_XDECREF(it);
1624 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001625}
1626
1627PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001628"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001629\n\
1630Calls the kernel kevent function.\n\
1631- changelist must be a list of kevent objects describing the changes\n\
1632 to be made to the kernel's watch list or None.\n\
1633- max_events lets you specify the maximum number of events that the\n\
1634 kernel will return.\n\
1635- timeout is the maximum time to wait in seconds, or else None,\n\
1636 to wait forever. timeout accepts floats for smaller timeouts, too.");
1637
1638
1639static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1641 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1642 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1643 kqueue_queue_close_doc},
1644 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1645 kqueue_queue_fileno_doc},
1646 {"control", (PyCFunction)kqueue_queue_control,
1647 METH_VARARGS , kqueue_queue_control_doc},
1648 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001649};
1650
1651static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 {"closed", (getter)kqueue_queue_get_closed, NULL,
1653 "True if the kqueue handler is closed"},
1654 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001655};
1656
1657PyDoc_STRVAR(kqueue_queue_doc,
1658"Kqueue syscall wrapper.\n\
1659\n\
1660For example, to start watching a socket for input:\n\
1661>>> kq = kqueue()\n\
1662>>> sock = socket()\n\
1663>>> sock.connect((host, port))\n\
1664>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1665\n\
1666To wait one second for it to become writeable:\n\
1667>>> kq.control(None, 1, 1000)\n\
1668\n\
1669To stop listening:\n\
1670>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1671
1672static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 PyVarObject_HEAD_INIT(NULL, 0)
1674 "select.kqueue", /* tp_name */
1675 sizeof(kqueue_queue_Object), /* tp_basicsize */
1676 0, /* tp_itemsize */
1677 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1678 0, /* tp_print */
1679 0, /* tp_getattr */
1680 0, /* tp_setattr */
1681 0, /* tp_reserved */
1682 0, /* tp_repr */
1683 0, /* tp_as_number */
1684 0, /* tp_as_sequence */
1685 0, /* tp_as_mapping */
1686 0, /* tp_hash */
1687 0, /* tp_call */
1688 0, /* tp_str */
1689 0, /* tp_getattro */
1690 0, /* tp_setattro */
1691 0, /* tp_as_buffer */
1692 Py_TPFLAGS_DEFAULT, /* tp_flags */
1693 kqueue_queue_doc, /* tp_doc */
1694 0, /* tp_traverse */
1695 0, /* tp_clear */
1696 0, /* tp_richcompare */
1697 0, /* tp_weaklistoffset */
1698 0, /* tp_iter */
1699 0, /* tp_iternext */
1700 kqueue_queue_methods, /* tp_methods */
1701 0, /* tp_members */
1702 kqueue_queue_getsetlist, /* tp_getset */
1703 0, /* tp_base */
1704 0, /* tp_dict */
1705 0, /* tp_descr_get */
1706 0, /* tp_descr_set */
1707 0, /* tp_dictoffset */
1708 0, /* tp_init */
1709 0, /* tp_alloc */
1710 kqueue_queue_new, /* tp_new */
1711 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001712};
1713
1714#endif /* HAVE_KQUEUE */
1715/* ************************************************************************ */
1716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001717PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001718"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1719\n\
1720Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001721The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001722rlist -- wait until ready for reading\n\
1723wlist -- wait until ready for writing\n\
1724xlist -- wait for an ``exceptional condition''\n\
1725If only one kind of condition is required, pass [] for the other lists.\n\
1726A file descriptor is either a socket or file object, or a small integer\n\
1727gotten from a fileno() method call on one of those.\n\
1728\n\
1729The optional 4th argument specifies a timeout in seconds; it may be\n\
1730a floating point number to specify fractions of seconds. If it is absent\n\
1731or None, the call will never time out.\n\
1732\n\
1733The return value is a tuple of three lists corresponding to the first three\n\
1734arguments; each contains the subset of the corresponding file descriptors\n\
1735that are ready.\n\
1736\n\
1737*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001738On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001739descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001740
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001741static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001743#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001745#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001747};
1748
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001749PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001750"This module supports asynchronous I/O on multiple file descriptors.\n\
1751\n\
1752*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001753On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001754
Martin v. Löwis1a214512008-06-11 05:26:20 +00001755
1756static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 PyModuleDef_HEAD_INIT,
1758 "select",
1759 module_doc,
1760 -1,
1761 select_methods,
1762 NULL,
1763 NULL,
1764 NULL,
1765 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001766};
1767
Mark Hammond62b1ab12002-07-23 06:31:15 +00001768PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001769PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 PyObject *m;
1772 m = PyModule_Create(&selectmodule);
1773 if (m == NULL)
1774 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 SelectError = PyErr_NewException("select.error", NULL, NULL);
1777 Py_INCREF(SelectError);
1778 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001780#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001781#ifdef HAVE_BROKEN_PIPE_BUF
1782#undef PIPE_BUF
1783#define PIPE_BUF 512
1784#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001786#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001787
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001788#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 if (select_have_broken_poll()) {
1791 if (PyObject_DelAttrString(m, "poll") == -1) {
1792 PyErr_Clear();
1793 }
1794 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001795#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001797#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 if (PyType_Ready(&poll_Type) < 0)
1799 return NULL;
1800 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1801 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1802 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1803 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1804 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1805 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001806
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001807#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001809#endif
1810#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001812#endif
1813#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001815#endif
1816#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001818#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001819#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001821#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001823#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001824
1825#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1827 if (PyType_Ready(&pyEpoll_Type) < 0)
1828 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 Py_INCREF(&pyEpoll_Type);
1831 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1834 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1835 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1836 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1837 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1838 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001839#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 /* Kernel 2.6.2+ */
1841 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001842#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1844 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1845 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1846 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1847 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1848 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001849#endif /* HAVE_EPOLL */
1850
1851#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 kqueue_event_Type.tp_new = PyType_GenericNew;
1853 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1854 if(PyType_Ready(&kqueue_event_Type) < 0)
1855 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 Py_INCREF(&kqueue_event_Type);
1858 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1861 if(PyType_Ready(&kqueue_queue_Type) < 0)
1862 return NULL;
1863 Py_INCREF(&kqueue_queue_Type);
1864 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1865
1866 /* event filters */
1867 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1868 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1869 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1870 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1871 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001872#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001874#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1876 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 /* event flags */
1879 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1880 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1881 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1882 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1883 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1884 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1887 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1890 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 /* READ WRITE filter flag */
1893 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 /* VNODE filter flags */
1896 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1897 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1898 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1899 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1900 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 /* PROC filter flags */
1905 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1907 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1908 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1909 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1914
1915 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001916#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1918 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1919 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001920#endif
1921
1922#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001924}