blob: 98b3108bf3ceb7c3c0eade9b5c79c8d7f29009aa [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)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200104 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000105
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);
Jesus Cea62a5c322012-07-19 21:31:26 +0200424 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 return NULL;
426 }
427 value = PyLong_FromLong(events);
428 if (value == NULL) {
429 Py_DECREF(key);
430 return NULL;
431 }
432 err = PyDict_SetItem(self->dict, key, value);
433 Py_DECREF(key);
434 Py_DECREF(value);
435 if (err < 0)
436 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 self->ufd_uptodate = 0;
439
440 Py_INCREF(Py_None);
441 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000442}
443
444
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000445PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000446"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000447Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448
449static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 PyObject *key;
453 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 fd = PyObject_AsFileDescriptor( o );
456 if (fd == -1)
457 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 /* Check whether the fd is already in the array */
460 key = PyLong_FromLong(fd);
461 if (key == NULL)
462 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 if (PyDict_DelItem(self->dict, key) == -1) {
465 Py_DECREF(key);
466 /* This will simply raise the KeyError set by PyDict_DelItem
467 if the file descriptor isn't registered. */
468 return NULL;
469 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 Py_DECREF(key);
472 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 Py_INCREF(Py_None);
475 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000476}
477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000478PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000479"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
480Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000481any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000482
483static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 PyObject *result_list = NULL, *tout = NULL;
487 int timeout = 0, poll_result, i, j;
488 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
491 return NULL;
492 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 /* Check values for timeout */
495 if (tout == NULL || tout == Py_None)
496 timeout = -1;
497 else if (!PyNumber_Check(tout)) {
498 PyErr_SetString(PyExc_TypeError,
499 "timeout must be an integer or None");
500 return NULL;
501 }
502 else {
503 tout = PyNumber_Long(tout);
504 if (!tout)
505 return NULL;
506 timeout = PyLong_AsLong(tout);
507 Py_DECREF(tout);
508 if (timeout == -1 && PyErr_Occurred())
509 return NULL;
510 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 /* Ensure the ufd array is up to date */
513 if (!self->ufd_uptodate)
514 if (update_ufd_array(self) == 0)
515 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 /* call poll() */
518 Py_BEGIN_ALLOW_THREADS
519 poll_result = poll(self->ufds, self->ufd_len, timeout);
520 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 if (poll_result < 0) {
523 PyErr_SetFromErrno(SelectError);
524 return NULL;
525 }
526
527 /* build the result list */
528
529 result_list = PyList_New(poll_result);
530 if (!result_list)
531 return NULL;
532 else {
533 for (i = 0, j = 0; j < poll_result; j++) {
534 /* skip to the next fired descriptor */
535 while (!self->ufds[i].revents) {
536 i++;
537 }
538 /* if we hit a NULL return, set value to NULL
539 and break out of loop; code at end will
540 clean up result_list */
541 value = PyTuple_New(2);
542 if (value == NULL)
543 goto error;
544 num = PyLong_FromLong(self->ufds[i].fd);
545 if (num == NULL) {
546 Py_DECREF(value);
547 goto error;
548 }
549 PyTuple_SET_ITEM(value, 0, num);
550
551 /* The &0xffff is a workaround for AIX. 'revents'
552 is a 16-bit short, and IBM assigned POLLNVAL
553 to be 0x8000, so the conversion to int results
554 in a negative number. See SF bug #923315. */
555 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
556 if (num == NULL) {
557 Py_DECREF(value);
558 goto error;
559 }
560 PyTuple_SET_ITEM(value, 1, num);
561 if ((PyList_SetItem(result_list, j, value)) == -1) {
562 Py_DECREF(value);
563 goto error;
564 }
565 i++;
566 }
567 }
568 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000569
570 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 Py_DECREF(result_list);
572 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000573}
574
575static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 {"register", (PyCFunction)poll_register,
577 METH_VARARGS, poll_register_doc},
578 {"modify", (PyCFunction)poll_modify,
579 METH_VARARGS, poll_modify_doc},
580 {"unregister", (PyCFunction)poll_unregister,
581 METH_O, poll_unregister_doc},
582 {"poll", (PyCFunction)poll_poll,
583 METH_VARARGS, poll_poll_doc},
584 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000585};
586
587static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000588newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 pollObject *self;
591 self = PyObject_New(pollObject, &poll_Type);
592 if (self == NULL)
593 return NULL;
594 /* ufd_uptodate is a Boolean, denoting whether the
595 array pointed to by ufds matches the contents of the dictionary. */
596 self->ufd_uptodate = 0;
597 self->ufds = NULL;
598 self->dict = PyDict_New();
599 if (self->dict == NULL) {
600 Py_DECREF(self);
601 return NULL;
602 }
603 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604}
605
606static void
607poll_dealloc(pollObject *self)
608{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 if (self->ufds != NULL)
610 PyMem_DEL(self->ufds);
611 Py_XDECREF(self->dict);
612 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000613}
614
Tim Peters0c322792002-07-17 16:49:03 +0000615static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 /* The ob_type field must be initialized in the module init function
617 * to be portable to Windows without using C++. */
618 PyVarObject_HEAD_INIT(NULL, 0)
619 "select.poll", /*tp_name*/
620 sizeof(pollObject), /*tp_basicsize*/
621 0, /*tp_itemsize*/
622 /* methods */
623 (destructor)poll_dealloc, /*tp_dealloc*/
624 0, /*tp_print*/
625 0, /*tp_getattr*/
626 0, /*tp_setattr*/
627 0, /*tp_reserved*/
628 0, /*tp_repr*/
629 0, /*tp_as_number*/
630 0, /*tp_as_sequence*/
631 0, /*tp_as_mapping*/
632 0, /*tp_hash*/
633 0, /*tp_call*/
634 0, /*tp_str*/
635 0, /*tp_getattro*/
636 0, /*tp_setattro*/
637 0, /*tp_as_buffer*/
638 Py_TPFLAGS_DEFAULT, /*tp_flags*/
639 0, /*tp_doc*/
640 0, /*tp_traverse*/
641 0, /*tp_clear*/
642 0, /*tp_richcompare*/
643 0, /*tp_weaklistoffset*/
644 0, /*tp_iter*/
645 0, /*tp_iternext*/
646 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000647};
648
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000649PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000650"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000651unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000652
653static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000654select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000658
659#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000661 * On some systems poll() sets errno on invalid file descriptors. We test
662 * for this at runtime because this bug may be fixed or introduced between
663 * OS releases.
664 */
665static int select_have_broken_poll(void)
666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 int poll_test;
668 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 /* Create a file descriptor to make invalid */
673 if (pipe(filedes) < 0) {
674 return 1;
675 }
676 poll_struct.fd = filedes[0];
677 close(filedes[0]);
678 close(filedes[1]);
679 poll_test = poll(&poll_struct, 1, 0);
680 if (poll_test < 0) {
681 return 1;
682 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
683 return 1;
684 }
685 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686}
687#endif /* __APPLE__ */
688
689#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000690
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000691#ifdef HAVE_EPOLL
692/* **************************************************************************
693 * epoll interface for Linux 2.6
694 *
695 * Written by Christian Heimes
696 * Inspired by Twisted's _epoll.pyx and select.poll()
697 */
698
699#ifdef HAVE_SYS_EPOLL_H
700#include <sys/epoll.h>
701#endif
702
703typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 PyObject_HEAD
705 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000706} pyEpoll_Object;
707
708static PyTypeObject pyEpoll_Type;
709#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
710
711static PyObject *
712pyepoll_err_closed(void)
713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
715 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000716}
717
718static int
719pyepoll_internal_close(pyEpoll_Object *self)
720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 int save_errno = 0;
722 if (self->epfd >= 0) {
723 int epfd = self->epfd;
724 self->epfd = -1;
725 Py_BEGIN_ALLOW_THREADS
726 if (close(epfd) < 0)
727 save_errno = errno;
728 Py_END_ALLOW_THREADS
729 }
730 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000731}
732
733static PyObject *
734newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 if (sizehint == -1) {
739 sizehint = FD_SETSIZE-1;
740 }
741 else if (sizehint < 1) {
742 PyErr_Format(PyExc_ValueError,
743 "sizehint must be greater zero, got %d",
744 sizehint);
745 return NULL;
746 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 assert(type != NULL && type->tp_alloc != NULL);
749 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
750 if (self == NULL)
751 return NULL;
752
753 if (fd == -1) {
754 Py_BEGIN_ALLOW_THREADS
755 self->epfd = epoll_create(sizehint);
756 Py_END_ALLOW_THREADS
757 }
758 else {
759 self->epfd = fd;
760 }
761 if (self->epfd < 0) {
762 Py_DECREF(self);
763 PyErr_SetFromErrno(PyExc_IOError);
764 return NULL;
765 }
766 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000767}
768
769
770static PyObject *
771pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 int sizehint = -1;
774 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
777 &sizehint))
778 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000781}
782
783
784static void
785pyepoll_dealloc(pyEpoll_Object *self)
786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 (void)pyepoll_internal_close(self);
788 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000789}
790
791static PyObject*
792pyepoll_close(pyEpoll_Object *self)
793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 errno = pyepoll_internal_close(self);
795 if (errno < 0) {
796 PyErr_SetFromErrno(PyExc_IOError);
797 return NULL;
798 }
799 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000800}
801
802PyDoc_STRVAR(pyepoll_close_doc,
803"close() -> None\n\
804\n\
805Close the epoll control file descriptor. Further operations on the epoll\n\
806object will raise an exception.");
807
808static PyObject*
809pyepoll_get_closed(pyEpoll_Object *self)
810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 if (self->epfd < 0)
812 Py_RETURN_TRUE;
813 else
814 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000815}
816
817static PyObject*
818pyepoll_fileno(pyEpoll_Object *self)
819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 if (self->epfd < 0)
821 return pyepoll_err_closed();
822 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000823}
824
825PyDoc_STRVAR(pyepoll_fileno_doc,
826"fileno() -> int\n\
827\n\
828Return the epoll control file descriptor.");
829
830static PyObject*
831pyepoll_fromfd(PyObject *cls, PyObject *args)
832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
836 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000839}
840
841PyDoc_STRVAR(pyepoll_fromfd_doc,
842"fromfd(fd) -> epoll\n\
843\n\
844Create an epoll object from a given control fd.");
845
846static PyObject *
847pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 struct epoll_event ev;
850 int result;
851 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 if (epfd < 0)
854 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 fd = PyObject_AsFileDescriptor(pfd);
857 if (fd == -1) {
858 return NULL;
859 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 switch(op) {
862 case EPOLL_CTL_ADD:
863 case EPOLL_CTL_MOD:
864 ev.events = events;
865 ev.data.fd = fd;
866 Py_BEGIN_ALLOW_THREADS
867 result = epoll_ctl(epfd, op, fd, &ev);
868 Py_END_ALLOW_THREADS
869 break;
870 case EPOLL_CTL_DEL:
871 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
872 * operation required a non-NULL pointer in event, even
873 * though this argument is ignored. */
874 Py_BEGIN_ALLOW_THREADS
875 result = epoll_ctl(epfd, op, fd, &ev);
876 if (errno == EBADF) {
877 /* fd already closed */
878 result = 0;
879 errno = 0;
880 }
881 Py_END_ALLOW_THREADS
882 break;
883 default:
884 result = -1;
885 errno = EINVAL;
886 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 if (result < 0) {
889 PyErr_SetFromErrno(PyExc_IOError);
890 return NULL;
891 }
892 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000893}
894
895static PyObject *
896pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 PyObject *pfd;
899 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
900 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
903 &pfd, &events)) {
904 return NULL;
905 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000908}
909
910PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000911"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000912\n\
Senthil Kumaran7d80bd12011-06-26 23:48:23 -0700913Registers a new fd or raises an IOError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000914fd is the target file descriptor of the operation.\n\
915events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000916is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
917\n\
918The epoll interface supports all file descriptors that support poll.");
919
920static PyObject *
921pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 PyObject *pfd;
924 unsigned int events;
925 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
928 &pfd, &events)) {
929 return NULL;
930 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000933}
934
935PyDoc_STRVAR(pyepoll_modify_doc,
936"modify(fd, eventmask) -> None\n\
937\n\
938fd is the target file descriptor of the operation\n\
939events is a bit set composed of the various EPOLL constants");
940
941static PyObject *
942pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
943{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 PyObject *pfd;
945 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
948 &pfd)) {
949 return NULL;
950 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000953}
954
955PyDoc_STRVAR(pyepoll_unregister_doc,
956"unregister(fd) -> None\n\
957\n\
958fd is the target file descriptor of the operation.");
959
960static PyObject *
961pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 double dtimeout = -1.;
964 int timeout;
965 int maxevents = -1;
966 int nfds, i;
967 PyObject *elist = NULL, *etuple = NULL;
968 struct epoll_event *evs = NULL;
969 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 if (self->epfd < 0)
972 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
975 &dtimeout, &maxevents)) {
976 return NULL;
977 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 if (dtimeout < 0) {
980 timeout = -1;
981 }
982 else if (dtimeout * 1000.0 > INT_MAX) {
983 PyErr_SetString(PyExc_OverflowError,
984 "timeout is too large");
985 return NULL;
986 }
987 else {
988 timeout = (int)(dtimeout * 1000.0);
989 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 if (maxevents == -1) {
992 maxevents = FD_SETSIZE-1;
993 }
994 else if (maxevents < 1) {
995 PyErr_Format(PyExc_ValueError,
996 "maxevents must be greater than 0, got %d",
997 maxevents);
998 return NULL;
999 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 evs = PyMem_New(struct epoll_event, maxevents);
1002 if (evs == NULL) {
1003 Py_DECREF(self);
1004 PyErr_NoMemory();
1005 return NULL;
1006 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 Py_BEGIN_ALLOW_THREADS
1009 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1010 Py_END_ALLOW_THREADS
1011 if (nfds < 0) {
1012 PyErr_SetFromErrno(PyExc_IOError);
1013 goto error;
1014 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 elist = PyList_New(nfds);
1017 if (elist == NULL) {
1018 goto error;
1019 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 for (i = 0; i < nfds; i++) {
1022 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1023 if (etuple == NULL) {
1024 Py_CLEAR(elist);
1025 goto error;
1026 }
1027 PyList_SET_ITEM(elist, i, etuple);
1028 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001029
Christian Heimesf6cd9672008-03-26 13:45:42 +00001030 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 PyMem_Free(evs);
1032 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001033}
1034
1035PyDoc_STRVAR(pyepoll_poll_doc,
1036"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1037\n\
1038Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1039in seconds (as float). -1 makes poll wait indefinitely.\n\
1040Up to maxevents are returned to the caller.");
1041
1042static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 {"fromfd", (PyCFunction)pyepoll_fromfd,
1044 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1045 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1046 pyepoll_close_doc},
1047 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1048 pyepoll_fileno_doc},
1049 {"modify", (PyCFunction)pyepoll_modify,
1050 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1051 {"register", (PyCFunction)pyepoll_register,
1052 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1053 {"unregister", (PyCFunction)pyepoll_unregister,
1054 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1055 {"poll", (PyCFunction)pyepoll_poll,
1056 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1057 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001058};
1059
1060static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 {"closed", (getter)pyepoll_get_closed, NULL,
1062 "True if the epoll handler is closed"},
1063 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001064};
1065
1066PyDoc_STRVAR(pyepoll_doc,
1067"select.epoll([sizehint=-1])\n\
1068\n\
1069Returns an epolling object\n\
1070\n\
1071sizehint must be a positive integer or -1 for the default size. The\n\
1072sizehint is used to optimize internal data structures. It doesn't limit\n\
1073the maximum number of monitored events.");
1074
1075static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 PyVarObject_HEAD_INIT(NULL, 0)
1077 "select.epoll", /* tp_name */
1078 sizeof(pyEpoll_Object), /* tp_basicsize */
1079 0, /* tp_itemsize */
1080 (destructor)pyepoll_dealloc, /* tp_dealloc */
1081 0, /* tp_print */
1082 0, /* tp_getattr */
1083 0, /* tp_setattr */
1084 0, /* tp_reserved */
1085 0, /* tp_repr */
1086 0, /* tp_as_number */
1087 0, /* tp_as_sequence */
1088 0, /* tp_as_mapping */
1089 0, /* tp_hash */
1090 0, /* tp_call */
1091 0, /* tp_str */
1092 PyObject_GenericGetAttr, /* tp_getattro */
1093 0, /* tp_setattro */
1094 0, /* tp_as_buffer */
1095 Py_TPFLAGS_DEFAULT, /* tp_flags */
1096 pyepoll_doc, /* tp_doc */
1097 0, /* tp_traverse */
1098 0, /* tp_clear */
1099 0, /* tp_richcompare */
1100 0, /* tp_weaklistoffset */
1101 0, /* tp_iter */
1102 0, /* tp_iternext */
1103 pyepoll_methods, /* tp_methods */
1104 0, /* tp_members */
1105 pyepoll_getsetlist, /* tp_getset */
1106 0, /* tp_base */
1107 0, /* tp_dict */
1108 0, /* tp_descr_get */
1109 0, /* tp_descr_set */
1110 0, /* tp_dictoffset */
1111 0, /* tp_init */
1112 0, /* tp_alloc */
1113 pyepoll_new, /* tp_new */
1114 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001115};
1116
1117#endif /* HAVE_EPOLL */
1118
1119#ifdef HAVE_KQUEUE
1120/* **************************************************************************
1121 * kqueue interface for BSD
1122 *
1123 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1124 * All rights reserved.
1125 *
1126 * Redistribution and use in source and binary forms, with or without
1127 * modification, are permitted provided that the following conditions
1128 * are met:
1129 * 1. Redistributions of source code must retain the above copyright
1130 * notice, this list of conditions and the following disclaimer.
1131 * 2. Redistributions in binary form must reproduce the above copyright
1132 * notice, this list of conditions and the following disclaimer in the
1133 * documentation and/or other materials provided with the distribution.
1134 *
1135 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1136 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1137 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1138 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1139 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1140 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1141 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1142 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1143 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1144 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1145 * SUCH DAMAGE.
1146 */
1147
1148#ifdef HAVE_SYS_EVENT_H
1149#include <sys/event.h>
1150#endif
1151
1152PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001153"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001154\n\
1155This object is the equivalent of the struct kevent for the C API.\n\
1156\n\
1157See the kqueue manpage for more detailed information about the meaning\n\
1158of the arguments.\n\
1159\n\
1160One minor note: while you might hope that udata could store a\n\
1161reference to a python object, it cannot, because it is impossible to\n\
1162keep a proper reference count of the object once it's passed into the\n\
1163kernel. Therefore, I have restricted it to only storing an integer. I\n\
1164recommend ignoring it and simply using the 'ident' field to key off\n\
1165of. You could also set up a dictionary on the python side to store a\n\
1166udata->object mapping.");
1167
1168typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 PyObject_HEAD
1170 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001171} kqueue_event_Object;
1172
1173static PyTypeObject kqueue_event_Type;
1174
1175#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1176
1177typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 PyObject_HEAD
1179 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001180} kqueue_queue_Object;
1181
1182static PyTypeObject kqueue_queue_Type;
1183
1184#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1185
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001186#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1187# error uintptr_t does not match void *!
1188#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1189# define T_UINTPTRT T_ULONGLONG
1190# define T_INTPTRT T_LONGLONG
1191# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1192# define UINTPTRT_FMT_UNIT "K"
1193# define INTPTRT_FMT_UNIT "L"
1194#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1195# define T_UINTPTRT T_ULONG
1196# define T_INTPTRT T_LONG
1197# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1198# define UINTPTRT_FMT_UNIT "k"
1199# define INTPTRT_FMT_UNIT "l"
1200#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1201# define T_UINTPTRT T_UINT
1202# define T_INTPTRT T_INT
1203# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1204# define UINTPTRT_FMT_UNIT "I"
1205# define INTPTRT_FMT_UNIT "i"
1206#else
1207# error uintptr_t does not match int, long, or long long!
1208#endif
1209
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001210/* Unfortunately, we can't store python objects in udata, because
1211 * kevents in the kernel can be removed without warning, which would
1212 * forever lose the refcount on the object stored with it.
1213 */
1214
1215#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1216static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1218 {"filter", T_SHORT, KQ_OFF(e.filter)},
1219 {"flags", T_USHORT, KQ_OFF(e.flags)},
1220 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1221 {"data", T_INTPTRT, KQ_OFF(e.data)},
1222 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1223 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001224};
1225#undef KQ_OFF
1226
1227static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001228
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001229kqueue_event_repr(kqueue_event_Object *s)
1230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 char buf[1024];
1232 PyOS_snprintf(
1233 buf, sizeof(buf),
1234 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1235 "data=0x%zd udata=%p>",
1236 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1237 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1238 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001239}
1240
1241static int
1242kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 PyObject *pfd;
1245 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1246 "data", "udata", NULL};
1247 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1252 &pfd, &(self->e.filter), &(self->e.flags),
1253 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1254 return -1;
1255 }
1256
1257 if (PyLong_Check(pfd)) {
1258 self->e.ident = PyLong_AsUintptr_t(pfd);
1259 }
1260 else {
1261 self->e.ident = PyObject_AsFileDescriptor(pfd);
1262 }
1263 if (PyErr_Occurred()) {
1264 return -1;
1265 }
1266 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001267}
1268
1269static PyObject *
1270kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 if (!kqueue_event_Check(o)) {
1276 if (op == Py_EQ || op == Py_NE) {
1277 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1278 Py_INCREF(res);
1279 return res;
1280 }
1281 PyErr_Format(PyExc_TypeError,
1282 "can't compare %.200s to %.200s",
1283 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1284 return NULL;
1285 }
1286 if (((result = s->e.ident - o->e.ident) == 0) &&
1287 ((result = s->e.filter - o->e.filter) == 0) &&
1288 ((result = s->e.flags - o->e.flags) == 0) &&
1289 ((result = s->e.fflags - o->e.fflags) == 0) &&
1290 ((result = s->e.data - o->e.data) == 0) &&
1291 ((result = s->e.udata - o->e.udata) == 0)
1292 ) {
1293 result = 0;
1294 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 switch (op) {
1297 case Py_EQ:
1298 result = (result == 0);
1299 break;
1300 case Py_NE:
1301 result = (result != 0);
1302 break;
1303 case Py_LE:
1304 result = (result <= 0);
1305 break;
1306 case Py_GE:
1307 result = (result >= 0);
1308 break;
1309 case Py_LT:
1310 result = (result < 0);
1311 break;
1312 case Py_GT:
1313 result = (result > 0);
1314 break;
1315 }
1316 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001317}
1318
1319static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 PyVarObject_HEAD_INIT(NULL, 0)
1321 "select.kevent", /* tp_name */
1322 sizeof(kqueue_event_Object), /* tp_basicsize */
1323 0, /* tp_itemsize */
1324 0, /* tp_dealloc */
1325 0, /* tp_print */
1326 0, /* tp_getattr */
1327 0, /* tp_setattr */
1328 0, /* tp_reserved */
1329 (reprfunc)kqueue_event_repr, /* tp_repr */
1330 0, /* tp_as_number */
1331 0, /* tp_as_sequence */
1332 0, /* tp_as_mapping */
1333 0, /* tp_hash */
1334 0, /* tp_call */
1335 0, /* tp_str */
1336 0, /* tp_getattro */
1337 0, /* tp_setattro */
1338 0, /* tp_as_buffer */
1339 Py_TPFLAGS_DEFAULT, /* tp_flags */
1340 kqueue_event_doc, /* tp_doc */
1341 0, /* tp_traverse */
1342 0, /* tp_clear */
1343 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1344 0, /* tp_weaklistoffset */
1345 0, /* tp_iter */
1346 0, /* tp_iternext */
1347 0, /* tp_methods */
1348 kqueue_event_members, /* tp_members */
1349 0, /* tp_getset */
1350 0, /* tp_base */
1351 0, /* tp_dict */
1352 0, /* tp_descr_get */
1353 0, /* tp_descr_set */
1354 0, /* tp_dictoffset */
1355 (initproc)kqueue_event_init, /* tp_init */
1356 0, /* tp_alloc */
1357 0, /* tp_new */
1358 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359};
1360
1361static PyObject *
1362kqueue_queue_err_closed(void)
1363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1365 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001366}
1367
1368static int
1369kqueue_queue_internal_close(kqueue_queue_Object *self)
1370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 int save_errno = 0;
1372 if (self->kqfd >= 0) {
1373 int kqfd = self->kqfd;
1374 self->kqfd = -1;
1375 Py_BEGIN_ALLOW_THREADS
1376 if (close(kqfd) < 0)
1377 save_errno = errno;
1378 Py_END_ALLOW_THREADS
1379 }
1380 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001381}
1382
1383static PyObject *
1384newKqueue_Object(PyTypeObject *type, SOCKET fd)
1385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 kqueue_queue_Object *self;
1387 assert(type != NULL && type->tp_alloc != NULL);
1388 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1389 if (self == NULL) {
1390 return NULL;
1391 }
1392
1393 if (fd == -1) {
1394 Py_BEGIN_ALLOW_THREADS
1395 self->kqfd = kqueue();
1396 Py_END_ALLOW_THREADS
1397 }
1398 else {
1399 self->kqfd = fd;
1400 }
1401 if (self->kqfd < 0) {
1402 Py_DECREF(self);
1403 PyErr_SetFromErrno(PyExc_IOError);
1404 return NULL;
1405 }
1406 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001407}
1408
1409static PyObject *
1410kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1411{
1412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if ((args != NULL && PyObject_Size(args)) ||
1414 (kwds != NULL && PyObject_Size(kwds))) {
1415 PyErr_SetString(PyExc_ValueError,
1416 "select.kqueue doesn't accept arguments");
1417 return NULL;
1418 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001421}
1422
1423static void
1424kqueue_queue_dealloc(kqueue_queue_Object *self)
1425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 kqueue_queue_internal_close(self);
1427 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428}
1429
1430static PyObject*
1431kqueue_queue_close(kqueue_queue_Object *self)
1432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 errno = kqueue_queue_internal_close(self);
1434 if (errno < 0) {
1435 PyErr_SetFromErrno(PyExc_IOError);
1436 return NULL;
1437 }
1438 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439}
1440
1441PyDoc_STRVAR(kqueue_queue_close_doc,
1442"close() -> None\n\
1443\n\
1444Close the kqueue control file descriptor. Further operations on the kqueue\n\
1445object will raise an exception.");
1446
1447static PyObject*
1448kqueue_queue_get_closed(kqueue_queue_Object *self)
1449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 if (self->kqfd < 0)
1451 Py_RETURN_TRUE;
1452 else
1453 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001454}
1455
1456static PyObject*
1457kqueue_queue_fileno(kqueue_queue_Object *self)
1458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 if (self->kqfd < 0)
1460 return kqueue_queue_err_closed();
1461 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001462}
1463
1464PyDoc_STRVAR(kqueue_queue_fileno_doc,
1465"fileno() -> int\n\
1466\n\
1467Return the kqueue control file descriptor.");
1468
1469static PyObject*
1470kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1475 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478}
1479
1480PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1481"fromfd(fd) -> kqueue\n\
1482\n\
1483Create a kqueue object from a given control fd.");
1484
1485static PyObject *
1486kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 int nevents = 0;
1489 int gotevents = 0;
1490 int nchanges = 0;
1491 int i = 0;
1492 PyObject *otimeout = NULL;
1493 PyObject *ch = NULL;
1494 PyObject *it = NULL, *ei = NULL;
1495 PyObject *result = NULL;
1496 struct kevent *evl = NULL;
1497 struct kevent *chl = NULL;
1498 struct timespec timeoutspec;
1499 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (self->kqfd < 0)
1502 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1505 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 if (nevents < 0) {
1508 PyErr_Format(PyExc_ValueError,
1509 "Length of eventlist must be 0 or positive, got %d",
1510 nevents);
1511 return NULL;
1512 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 if (otimeout == Py_None || otimeout == NULL) {
1515 ptimeoutspec = NULL;
1516 }
1517 else if (PyNumber_Check(otimeout)) {
1518 double timeout;
1519 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 timeout = PyFloat_AsDouble(otimeout);
1522 if (timeout == -1 && PyErr_Occurred())
1523 return NULL;
1524 if (timeout > (double)LONG_MAX) {
1525 PyErr_SetString(PyExc_OverflowError,
1526 "timeout period too long");
1527 return NULL;
1528 }
1529 if (timeout < 0) {
1530 PyErr_SetString(PyExc_ValueError,
1531 "timeout must be positive or None");
1532 return NULL;
1533 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 seconds = (long)timeout;
1536 timeout = timeout - (double)seconds;
1537 timeoutspec.tv_sec = seconds;
1538 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1539 ptimeoutspec = &timeoutspec;
1540 }
1541 else {
1542 PyErr_Format(PyExc_TypeError,
1543 "timeout argument must be an number "
1544 "or None, got %.200s",
1545 Py_TYPE(otimeout)->tp_name);
1546 return NULL;
1547 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 if (ch != NULL && ch != Py_None) {
1550 it = PyObject_GetIter(ch);
1551 if (it == NULL) {
1552 PyErr_SetString(PyExc_TypeError,
1553 "changelist is not iterable");
1554 return NULL;
1555 }
1556 nchanges = PyObject_Size(ch);
1557 if (nchanges < 0) {
1558 goto error;
1559 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 chl = PyMem_New(struct kevent, nchanges);
1562 if (chl == NULL) {
1563 PyErr_NoMemory();
1564 goto error;
1565 }
1566 i = 0;
1567 while ((ei = PyIter_Next(it)) != NULL) {
1568 if (!kqueue_event_Check(ei)) {
1569 Py_DECREF(ei);
1570 PyErr_SetString(PyExc_TypeError,
1571 "changelist must be an iterable of "
1572 "select.kevent objects");
1573 goto error;
1574 } else {
1575 chl[i++] = ((kqueue_event_Object *)ei)->e;
1576 }
1577 Py_DECREF(ei);
1578 }
1579 }
1580 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 /* event list */
1583 if (nevents) {
1584 evl = PyMem_New(struct kevent, nevents);
1585 if (evl == NULL) {
1586 PyErr_NoMemory();
1587 goto error;
1588 }
1589 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 Py_BEGIN_ALLOW_THREADS
1592 gotevents = kevent(self->kqfd, chl, nchanges,
1593 evl, nevents, ptimeoutspec);
1594 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 if (gotevents == -1) {
1597 PyErr_SetFromErrno(PyExc_OSError);
1598 goto error;
1599 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 result = PyList_New(gotevents);
1602 if (result == NULL) {
1603 goto error;
1604 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 for (i = 0; i < gotevents; i++) {
1607 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1610 if (ch == NULL) {
1611 goto error;
1612 }
1613 ch->e = evl[i];
1614 PyList_SET_ITEM(result, i, (PyObject *)ch);
1615 }
1616 PyMem_Free(chl);
1617 PyMem_Free(evl);
1618 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001619
1620 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyMem_Free(chl);
1622 PyMem_Free(evl);
1623 Py_XDECREF(result);
1624 Py_XDECREF(it);
1625 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001626}
1627
1628PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001629"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630\n\
1631Calls the kernel kevent function.\n\
1632- changelist must be a list of kevent objects describing the changes\n\
1633 to be made to the kernel's watch list or None.\n\
1634- max_events lets you specify the maximum number of events that the\n\
1635 kernel will return.\n\
1636- timeout is the maximum time to wait in seconds, or else None,\n\
1637 to wait forever. timeout accepts floats for smaller timeouts, too.");
1638
1639
1640static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1642 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1643 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1644 kqueue_queue_close_doc},
1645 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1646 kqueue_queue_fileno_doc},
1647 {"control", (PyCFunction)kqueue_queue_control,
1648 METH_VARARGS , kqueue_queue_control_doc},
1649 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001650};
1651
1652static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 {"closed", (getter)kqueue_queue_get_closed, NULL,
1654 "True if the kqueue handler is closed"},
1655 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001656};
1657
1658PyDoc_STRVAR(kqueue_queue_doc,
1659"Kqueue syscall wrapper.\n\
1660\n\
1661For example, to start watching a socket for input:\n\
1662>>> kq = kqueue()\n\
1663>>> sock = socket()\n\
1664>>> sock.connect((host, port))\n\
1665>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1666\n\
1667To wait one second for it to become writeable:\n\
1668>>> kq.control(None, 1, 1000)\n\
1669\n\
1670To stop listening:\n\
1671>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1672
1673static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 PyVarObject_HEAD_INIT(NULL, 0)
1675 "select.kqueue", /* tp_name */
1676 sizeof(kqueue_queue_Object), /* tp_basicsize */
1677 0, /* tp_itemsize */
1678 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1679 0, /* tp_print */
1680 0, /* tp_getattr */
1681 0, /* tp_setattr */
1682 0, /* tp_reserved */
1683 0, /* tp_repr */
1684 0, /* tp_as_number */
1685 0, /* tp_as_sequence */
1686 0, /* tp_as_mapping */
1687 0, /* tp_hash */
1688 0, /* tp_call */
1689 0, /* tp_str */
1690 0, /* tp_getattro */
1691 0, /* tp_setattro */
1692 0, /* tp_as_buffer */
1693 Py_TPFLAGS_DEFAULT, /* tp_flags */
1694 kqueue_queue_doc, /* tp_doc */
1695 0, /* tp_traverse */
1696 0, /* tp_clear */
1697 0, /* tp_richcompare */
1698 0, /* tp_weaklistoffset */
1699 0, /* tp_iter */
1700 0, /* tp_iternext */
1701 kqueue_queue_methods, /* tp_methods */
1702 0, /* tp_members */
1703 kqueue_queue_getsetlist, /* tp_getset */
1704 0, /* tp_base */
1705 0, /* tp_dict */
1706 0, /* tp_descr_get */
1707 0, /* tp_descr_set */
1708 0, /* tp_dictoffset */
1709 0, /* tp_init */
1710 0, /* tp_alloc */
1711 kqueue_queue_new, /* tp_new */
1712 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001713};
1714
1715#endif /* HAVE_KQUEUE */
1716/* ************************************************************************ */
1717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001718PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001719"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1720\n\
1721Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001722The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001723rlist -- wait until ready for reading\n\
1724wlist -- wait until ready for writing\n\
1725xlist -- wait for an ``exceptional condition''\n\
1726If only one kind of condition is required, pass [] for the other lists.\n\
1727A file descriptor is either a socket or file object, or a small integer\n\
1728gotten from a fileno() method call on one of those.\n\
1729\n\
1730The optional 4th argument specifies a timeout in seconds; it may be\n\
1731a floating point number to specify fractions of seconds. If it is absent\n\
1732or None, the call will never time out.\n\
1733\n\
1734The return value is a tuple of three lists corresponding to the first three\n\
1735arguments; each contains the subset of the corresponding file descriptors\n\
1736that are ready.\n\
1737\n\
1738*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001739On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001740descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001741
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001742static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001744#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001746#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001748};
1749
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001750PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001751"This module supports asynchronous I/O on multiple file descriptors.\n\
1752\n\
1753*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001754On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001755
Martin v. Löwis1a214512008-06-11 05:26:20 +00001756
1757static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 PyModuleDef_HEAD_INIT,
1759 "select",
1760 module_doc,
1761 -1,
1762 select_methods,
1763 NULL,
1764 NULL,
1765 NULL,
1766 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001767};
1768
Mark Hammond62b1ab12002-07-23 06:31:15 +00001769PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001770PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 PyObject *m;
1773 m = PyModule_Create(&selectmodule);
1774 if (m == NULL)
1775 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 SelectError = PyErr_NewException("select.error", NULL, NULL);
1778 Py_INCREF(SelectError);
1779 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001780
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001781#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001782#ifdef HAVE_BROKEN_PIPE_BUF
1783#undef PIPE_BUF
1784#define PIPE_BUF 512
1785#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001787#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001788
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001789#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001790#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 if (select_have_broken_poll()) {
1792 if (PyObject_DelAttrString(m, "poll") == -1) {
1793 PyErr_Clear();
1794 }
1795 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 if (PyType_Ready(&poll_Type) < 0)
1800 return NULL;
1801 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1802 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1803 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1804 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1805 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1806 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001807
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001808#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001810#endif
1811#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001813#endif
1814#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001816#endif
1817#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001819#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001820#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001822#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001824#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001825
1826#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1828 if (PyType_Ready(&pyEpoll_Type) < 0)
1829 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 Py_INCREF(&pyEpoll_Type);
1832 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1835 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1836 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1837 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1838 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1839 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001840#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 /* Kernel 2.6.2+ */
1842 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001843#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1845 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1846 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1847 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1848 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1849 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001850#endif /* HAVE_EPOLL */
1851
1852#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 kqueue_event_Type.tp_new = PyType_GenericNew;
1854 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1855 if(PyType_Ready(&kqueue_event_Type) < 0)
1856 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 Py_INCREF(&kqueue_event_Type);
1859 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1862 if(PyType_Ready(&kqueue_queue_Type) < 0)
1863 return NULL;
1864 Py_INCREF(&kqueue_queue_Type);
1865 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1866
1867 /* event filters */
1868 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1869 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1870 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1871 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1872 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001875#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1877 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 /* event flags */
1880 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1881 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1882 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1883 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1884 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1885 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1888 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1891 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 /* READ WRITE filter flag */
1894 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 /* VNODE filter flags */
1897 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1898 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1899 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1900 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1903 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 /* PROC filter flags */
1906 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1907 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1908 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1909 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1910 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1915
1916 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001917#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1919 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1920 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921#endif
1922
1923#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001925}