blob: 7cec49bc41022e1d12bb888f7cfc26c686368b17 [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
Jesus Cead8b9ae62011-11-14 19:07:41 +010010#ifdef HAVE_SYS_DEVPOLL_H
11#include <sys/resource.h>
12#include <sys/devpoll.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018#ifdef __APPLE__
19 /* Perform runtime testing for a broken poll on OSX to make it easier
20 * to use the same binary on multiple releases of the OS.
21 */
22#undef HAVE_BROKEN_POLL
23#endif
24
Tim Petersd92dfe02000-12-12 01:18:41 +000025/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
26 64 is too small (too many people have bumped into that limit).
27 Here we boost it.
28 Users who want even more than the boosted limit should #define
29 FD_SETSIZE higher before this; e.g., via compiler /D switch.
30*/
31#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
32#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000034
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000035#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000036#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000037#elif defined(HAVE_SYS_POLL_H)
38#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000039#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000040
Guido van Rossum37273171996-12-09 18:47:43 +000041#ifdef __sgi
42/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000043extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000044#endif
45
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000048#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000050#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <sys/time.h>
52#include <utils.h>
53#endif
54
Guido van Rossum6f489d91996-06-28 20:15:15 +000055#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000056# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000057# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000058#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000060# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061# include <socket.h>
62# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000063#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000064
Barry Warsawc1cb3601996-12-12 22:16:21 +000065/* list of Python objects and their file descriptor */
66typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 PyObject *obj; /* owned reference */
68 SOCKET fd;
69 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000070} pylist;
71
Barry Warsawc1cb3601996-12-12 22:16:21 +000072static void
Tim Peters4b046c22001-08-16 21:59:46 +000073reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 int i;
76 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
77 Py_XDECREF(fd2obj[i].obj);
78 fd2obj[i].obj = NULL;
79 }
80 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000081}
82
83
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000084/* returns -1 and sets the Python exception if an error occurred, otherwise
85 returns a number >= 0
86*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000087static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000088seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 int max = -1;
91 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000092 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyObject* fast_seq = NULL;
94 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
97 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000098
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000099 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 if (!fast_seq)
101 return -1;
102
103 len = PySequence_Fast_GET_SIZE(fast_seq);
104
105 for (i = 0; i < len; i++) {
106 SOCKET v;
107
108 /* any intervening fileno() calls could decr this refcnt */
109 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200110 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 Py_INCREF(o);
113 v = PyObject_AsFileDescriptor( o );
114 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000116#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200119 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 PyErr_SetString(PyExc_ValueError,
121 "filedescriptor out of range in select()");
122 goto finally;
123 }
124 if (v > max)
125 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 /* add object and its file descriptor to the list */
130 if (index >= FD_SETSIZE) {
131 PyErr_SetString(PyExc_ValueError,
132 "too many file descriptors in select()");
133 goto finally;
134 }
135 fd2obj[index].obj = o;
136 fd2obj[index].fd = v;
137 fd2obj[index].sentinel = 0;
138 fd2obj[++index].sentinel = -1;
139 }
140 Py_DECREF(fast_seq);
141 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142
143 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 Py_XDECREF(o);
145 Py_DECREF(fast_seq);
146 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000147}
148
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149/* returns NULL and sets the Python exception if an error occurred */
150static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000151set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int i, j, count=0;
154 PyObject *list, *o;
155 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
158 if (FD_ISSET(fd2obj[j].fd, set))
159 count++;
160 }
161 list = PyList_New(count);
162 if (!list)
163 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 i = 0;
166 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
167 fd = fd2obj[j].fd;
168 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 o = fd2obj[j].obj;
170 fd2obj[j].obj = NULL;
171 /* transfer ownership */
172 if (PyList_SetItem(list, i, o) < 0)
173 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 i++;
176 }
177 }
178 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000179 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 Py_DECREF(list);
181 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000182}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000183
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#undef SELECT_USES_HEAP
185#if FD_SETSIZE > 1024
186#define SELECT_USES_HEAP
187#endif /* FD_SETSIZE > 1024 */
188
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000189static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000190select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000191{
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 /* XXX: All this should probably be implemented as follows:
196 * - find the highest descriptor we're interested in
197 * - add one
198 * - that's the size
199 * See: Stevens, APitUE, $12.5.1
200 */
201 pylist rfd2obj[FD_SETSIZE + 1];
202 pylist wfd2obj[FD_SETSIZE + 1];
203 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000204#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 PyObject *ifdlist, *ofdlist, *efdlist;
206 PyObject *ret = NULL;
207 PyObject *tout = Py_None;
208 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 int imax, omax, emax, max;
211 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 /* convert arguments */
214 if (!PyArg_UnpackTuple(args, "select", 3, 4,
215 &ifdlist, &ofdlist, &efdlist, &tout))
216 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 if (tout == Py_None)
219 tvp = (struct timeval *)0;
220 else if (!PyNumber_Check(tout)) {
221 PyErr_SetString(PyExc_TypeError,
222 "timeout must be a float or None");
223 return NULL;
224 }
225 else {
Victor Stinnerb2a37732012-03-14 00:20:51 +0100226#ifdef MS_WINDOWS
227 time_t sec;
228 if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 return NULL;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100230 assert(sizeof(tv.tv_sec) == sizeof(long));
231#if SIZEOF_TIME_T > SIZEOF_LONG
232 if (sec > LONG_MAX) {
233 PyErr_SetString(PyExc_OverflowError,
234 "timeout is too large");
235 return NULL;
236 }
237#endif
238 tv.tv_sec = (long)sec;
239#else
Brett Cannon8798ad32012-04-07 14:59:29 -0400240 /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4
241 bytes as required), but no longer defined by a long. */
Benjamin Peterson6f3e5e42012-09-11 12:05:05 -0400242 long tv_usec;
Brett Cannon8798ad32012-04-07 14:59:29 -0400243 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1)
Victor Stinnerb2a37732012-03-14 00:20:51 +0100244 return NULL;
Brett Cannon8798ad32012-04-07 14:59:29 -0400245 tv.tv_usec = tv_usec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100246#endif
Victor Stinner5d272cc2012-03-13 13:35:55 +0100247 if (tv.tv_sec < 0) {
248 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 return NULL;
250 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 tvp = &tv;
252 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000253
Guido van Rossumed233a51992-06-23 09:07:03 +0000254
Barry Warsawb44740f2001-08-16 16:52:59 +0000255#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 /* Allocate memory for the lists */
257 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
258 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
259 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
260 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
261 if (rfd2obj) PyMem_DEL(rfd2obj);
262 if (wfd2obj) PyMem_DEL(wfd2obj);
263 if (efd2obj) PyMem_DEL(efd2obj);
264 return PyErr_NoMemory();
265 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000266#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 /* Convert sequences to fd_sets, and get maximum fd number
268 * propagates the Python exception set in seq2set()
269 */
270 rfd2obj[0].sentinel = -1;
271 wfd2obj[0].sentinel = -1;
272 efd2obj[0].sentinel = -1;
273 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
274 goto finally;
275 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
276 goto finally;
277 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
278 goto finally;
279 max = imax;
280 if (omax > max) max = omax;
281 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 Py_BEGIN_ALLOW_THREADS
284 n = select(max, &ifdset, &ofdset, &efdset, tvp);
285 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000286
Thomas Heller106f4c72002-09-24 16:51:00 +0000287#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200289 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000291#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200293 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000295#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 else {
297 /* any of these three calls can raise an exception. it's more
298 convenient to test for this after all three calls... but
299 is that acceptable?
300 */
301 ifdlist = set2list(&ifdset, rfd2obj);
302 ofdlist = set2list(&ofdset, wfd2obj);
303 efdlist = set2list(&efdset, efd2obj);
304 if (PyErr_Occurred())
305 ret = NULL;
306 else
307 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 Py_DECREF(ifdlist);
310 Py_DECREF(ofdlist);
311 Py_DECREF(efdlist);
312 }
313
Barry Warsawc1cb3601996-12-12 22:16:21 +0000314 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 reap_obj(rfd2obj);
316 reap_obj(wfd2obj);
317 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000318#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 PyMem_DEL(rfd2obj);
320 PyMem_DEL(wfd2obj);
321 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000322#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000324}
325
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000326#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000328 * poll() support
329 */
330
331typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 PyObject_HEAD
333 PyObject *dict;
334 int ufd_uptodate;
335 int ufd_len;
336 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337} pollObject;
338
Jeremy Hylton938ace62002-07-17 16:30:39 +0000339static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342 contained within a pollObject. Return 1 on success, 0 on an error.
343*/
344
345static int
346update_ufd_array(pollObject *self)
347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 Py_ssize_t i, pos;
349 PyObject *key, *value;
350 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 self->ufd_len = PyDict_Size(self->dict);
353 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
354 if (self->ufds == NULL) {
355 self->ufds = old_ufds;
356 PyErr_NoMemory();
357 return 0;
358 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 i = pos = 0;
361 while (PyDict_Next(self->dict, &pos, &key, &value)) {
362 self->ufds[i].fd = PyLong_AsLong(key);
363 self->ufds[i].events = (short)PyLong_AsLong(value);
364 i++;
365 }
366 self->ufd_uptodate = 1;
367 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000368}
369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000370PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371"register(fd [, eventmask] ) -> None\n\n\
372Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000373fd -- either an integer, or an object with a fileno() method returning an\n\
374 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000375events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000376
377static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 PyObject *o, *key, *value;
381 int fd, events = POLLIN | POLLPRI | POLLOUT;
382 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
385 return NULL;
386 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 fd = PyObject_AsFileDescriptor(o);
389 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 /* Add entry to the internal dictionary: the key is the
392 file descriptor, and the value is the event mask. */
393 key = PyLong_FromLong(fd);
394 if (key == NULL)
395 return NULL;
396 value = PyLong_FromLong(events);
397 if (value == NULL) {
398 Py_DECREF(key);
399 return NULL;
400 }
401 err = PyDict_SetItem(self->dict, key, value);
402 Py_DECREF(key);
403 Py_DECREF(value);
404 if (err < 0)
405 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 self->ufd_uptodate = 0;
408
409 Py_INCREF(Py_None);
410 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000411}
412
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000413PyDoc_STRVAR(poll_modify_doc,
414"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000415Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000416fd -- either an integer, or an object with a fileno() method returning an\n\
417 int.\n\
418events -- an optional bitmask describing the type of events to check for");
419
420static PyObject *
421poll_modify(pollObject *self, PyObject *args)
422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 PyObject *o, *key, *value;
424 int fd, events;
425 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
428 return NULL;
429 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 fd = PyObject_AsFileDescriptor(o);
432 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 /* Modify registered fd */
435 key = PyLong_FromLong(fd);
436 if (key == NULL)
437 return NULL;
438 if (PyDict_GetItem(self->dict, key) == NULL) {
439 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200440 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200441 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 return NULL;
443 }
444 value = PyLong_FromLong(events);
445 if (value == NULL) {
446 Py_DECREF(key);
447 return NULL;
448 }
449 err = PyDict_SetItem(self->dict, key, value);
450 Py_DECREF(key);
451 Py_DECREF(value);
452 if (err < 0)
453 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 self->ufd_uptodate = 0;
456
457 Py_INCREF(Py_None);
458 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000459}
460
461
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000462PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000464Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465
466static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 PyObject *key;
470 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 fd = PyObject_AsFileDescriptor( o );
473 if (fd == -1)
474 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 /* Check whether the fd is already in the array */
477 key = PyLong_FromLong(fd);
478 if (key == NULL)
479 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 if (PyDict_DelItem(self->dict, key) == -1) {
482 Py_DECREF(key);
483 /* This will simply raise the KeyError set by PyDict_DelItem
484 if the file descriptor isn't registered. */
485 return NULL;
486 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 Py_DECREF(key);
489 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 Py_INCREF(Py_None);
492 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493}
494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000495PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
497Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000498any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000499
500static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 PyObject *result_list = NULL, *tout = NULL;
504 int timeout = 0, poll_result, i, j;
505 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
508 return NULL;
509 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 /* Check values for timeout */
512 if (tout == NULL || tout == Py_None)
513 timeout = -1;
514 else if (!PyNumber_Check(tout)) {
515 PyErr_SetString(PyExc_TypeError,
516 "timeout must be an integer or None");
517 return NULL;
518 }
519 else {
520 tout = PyNumber_Long(tout);
521 if (!tout)
522 return NULL;
523 timeout = PyLong_AsLong(tout);
524 Py_DECREF(tout);
525 if (timeout == -1 && PyErr_Occurred())
526 return NULL;
527 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 /* Ensure the ufd array is up to date */
530 if (!self->ufd_uptodate)
531 if (update_ufd_array(self) == 0)
532 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 /* call poll() */
535 Py_BEGIN_ALLOW_THREADS
536 poll_result = poll(self->ufds, self->ufd_len, timeout);
537 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200540 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 return NULL;
542 }
543
544 /* build the result list */
545
546 result_list = PyList_New(poll_result);
547 if (!result_list)
548 return NULL;
549 else {
550 for (i = 0, j = 0; j < poll_result; j++) {
551 /* skip to the next fired descriptor */
552 while (!self->ufds[i].revents) {
553 i++;
554 }
555 /* if we hit a NULL return, set value to NULL
556 and break out of loop; code at end will
557 clean up result_list */
558 value = PyTuple_New(2);
559 if (value == NULL)
560 goto error;
561 num = PyLong_FromLong(self->ufds[i].fd);
562 if (num == NULL) {
563 Py_DECREF(value);
564 goto error;
565 }
566 PyTuple_SET_ITEM(value, 0, num);
567
568 /* The &0xffff is a workaround for AIX. 'revents'
569 is a 16-bit short, and IBM assigned POLLNVAL
570 to be 0x8000, so the conversion to int results
571 in a negative number. See SF bug #923315. */
572 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
573 if (num == NULL) {
574 Py_DECREF(value);
575 goto error;
576 }
577 PyTuple_SET_ITEM(value, 1, num);
578 if ((PyList_SetItem(result_list, j, value)) == -1) {
579 Py_DECREF(value);
580 goto error;
581 }
582 i++;
583 }
584 }
585 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000586
587 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 Py_DECREF(result_list);
589 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000590}
591
592static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 {"register", (PyCFunction)poll_register,
594 METH_VARARGS, poll_register_doc},
595 {"modify", (PyCFunction)poll_modify,
596 METH_VARARGS, poll_modify_doc},
597 {"unregister", (PyCFunction)poll_unregister,
598 METH_O, poll_unregister_doc},
599 {"poll", (PyCFunction)poll_poll,
600 METH_VARARGS, poll_poll_doc},
601 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000602};
603
604static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000605newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000606{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 pollObject *self;
608 self = PyObject_New(pollObject, &poll_Type);
609 if (self == NULL)
610 return NULL;
611 /* ufd_uptodate is a Boolean, denoting whether the
612 array pointed to by ufds matches the contents of the dictionary. */
613 self->ufd_uptodate = 0;
614 self->ufds = NULL;
615 self->dict = PyDict_New();
616 if (self->dict == NULL) {
617 Py_DECREF(self);
618 return NULL;
619 }
620 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000621}
622
623static void
624poll_dealloc(pollObject *self)
625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 if (self->ufds != NULL)
627 PyMem_DEL(self->ufds);
628 Py_XDECREF(self->dict);
629 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000630}
631
Tim Peters0c322792002-07-17 16:49:03 +0000632static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 /* The ob_type field must be initialized in the module init function
634 * to be portable to Windows without using C++. */
635 PyVarObject_HEAD_INIT(NULL, 0)
636 "select.poll", /*tp_name*/
637 sizeof(pollObject), /*tp_basicsize*/
638 0, /*tp_itemsize*/
639 /* methods */
640 (destructor)poll_dealloc, /*tp_dealloc*/
641 0, /*tp_print*/
642 0, /*tp_getattr*/
643 0, /*tp_setattr*/
644 0, /*tp_reserved*/
645 0, /*tp_repr*/
646 0, /*tp_as_number*/
647 0, /*tp_as_sequence*/
648 0, /*tp_as_mapping*/
649 0, /*tp_hash*/
650 0, /*tp_call*/
651 0, /*tp_str*/
652 0, /*tp_getattro*/
653 0, /*tp_setattro*/
654 0, /*tp_as_buffer*/
655 Py_TPFLAGS_DEFAULT, /*tp_flags*/
656 0, /*tp_doc*/
657 0, /*tp_traverse*/
658 0, /*tp_clear*/
659 0, /*tp_richcompare*/
660 0, /*tp_weaklistoffset*/
661 0, /*tp_iter*/
662 0, /*tp_iternext*/
663 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000664};
665
Jesus Cead8b9ae62011-11-14 19:07:41 +0100666#ifdef HAVE_SYS_DEVPOLL_H
667typedef struct {
668 PyObject_HEAD
669 int fd_devpoll;
670 int max_n_fds;
671 int n_fds;
672 struct pollfd *fds;
673} devpollObject;
674
675static PyTypeObject devpoll_Type;
676
677static int devpoll_flush(devpollObject *self)
678{
679 int size, n;
680
681 if (!self->n_fds) return 0;
682
683 size = sizeof(struct pollfd)*self->n_fds;
684 self->n_fds = 0;
685
686 Py_BEGIN_ALLOW_THREADS
687 n = write(self->fd_devpoll, self->fds, size);
688 Py_END_ALLOW_THREADS
689
690 if (n == -1 ) {
691 PyErr_SetFromErrno(PyExc_IOError);
692 return -1;
693 }
694 if (n < size) {
695 /*
696 ** Data writed to /dev/poll is a binary data structure. It is not
697 ** clear what to do if a partial write occurred. For now, raise
698 ** an exception and see if we actually found this problem in
699 ** the wild.
700 ** See http://bugs.python.org/issue6397.
701 */
702 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
703 "Please, report at http://bugs.python.org/. "
704 "Data to report: Size tried: %d, actual size written: %d.",
705 size, n);
706 return -1;
707 }
708 return 0;
709}
710
711static PyObject *
712internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
713{
714 PyObject *o;
715 int fd, events = POLLIN | POLLPRI | POLLOUT;
716
717 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
718 return NULL;
719 }
720
721 fd = PyObject_AsFileDescriptor(o);
722 if (fd == -1) return NULL;
723
724 if (remove) {
725 self->fds[self->n_fds].fd = fd;
726 self->fds[self->n_fds].events = POLLREMOVE;
727
728 if (++self->n_fds == self->max_n_fds) {
729 if (devpoll_flush(self))
730 return NULL;
731 }
732 }
733
734 self->fds[self->n_fds].fd = fd;
735 self->fds[self->n_fds].events = events;
736
737 if (++self->n_fds == self->max_n_fds) {
738 if (devpoll_flush(self))
739 return NULL;
740 }
741
742 Py_RETURN_NONE;
743}
744
745PyDoc_STRVAR(devpoll_register_doc,
746"register(fd [, eventmask] ) -> None\n\n\
747Register a file descriptor with the polling object.\n\
748fd -- either an integer, or an object with a fileno() method returning an\n\
749 int.\n\
750events -- an optional bitmask describing the type of events to check for");
751
752static PyObject *
753devpoll_register(devpollObject *self, PyObject *args)
754{
755 return internal_devpoll_register(self, args, 0);
756}
757
758PyDoc_STRVAR(devpoll_modify_doc,
759"modify(fd[, eventmask]) -> None\n\n\
760Modify a possible already registered file descriptor.\n\
761fd -- either an integer, or an object with a fileno() method returning an\n\
762 int.\n\
763events -- an optional bitmask describing the type of events to check for");
764
765static PyObject *
766devpoll_modify(devpollObject *self, PyObject *args)
767{
768 return internal_devpoll_register(self, args, 1);
769}
770
771
772PyDoc_STRVAR(devpoll_unregister_doc,
773"unregister(fd) -> None\n\n\
774Remove a file descriptor being tracked by the polling object.");
775
776static PyObject *
777devpoll_unregister(devpollObject *self, PyObject *o)
778{
779 int fd;
780
781 fd = PyObject_AsFileDescriptor( o );
782 if (fd == -1)
783 return NULL;
784
785 self->fds[self->n_fds].fd = fd;
786 self->fds[self->n_fds].events = POLLREMOVE;
787
788 if (++self->n_fds == self->max_n_fds) {
789 if (devpoll_flush(self))
790 return NULL;
791 }
792
793 Py_RETURN_NONE;
794}
795
796PyDoc_STRVAR(devpoll_poll_doc,
797"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
798Polls the set of registered file descriptors, returning a list containing \n\
799any descriptors that have events or errors to report.");
800
801static PyObject *
802devpoll_poll(devpollObject *self, PyObject *args)
803{
804 struct dvpoll dvp;
805 PyObject *result_list = NULL, *tout = NULL;
806 int poll_result, i;
807 long timeout;
808 PyObject *value, *num1, *num2;
809
810 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
811 return NULL;
812 }
813
814 /* Check values for timeout */
815 if (tout == NULL || tout == Py_None)
816 timeout = -1;
817 else if (!PyNumber_Check(tout)) {
818 PyErr_SetString(PyExc_TypeError,
819 "timeout must be an integer or None");
820 return NULL;
821 }
822 else {
823 tout = PyNumber_Long(tout);
824 if (!tout)
825 return NULL;
826 timeout = PyLong_AsLong(tout);
827 Py_DECREF(tout);
828 if (timeout == -1 && PyErr_Occurred())
829 return NULL;
830 }
831
832 if ((timeout < -1) || (timeout > INT_MAX)) {
833 PyErr_SetString(PyExc_OverflowError,
834 "timeout is out of range");
835 return NULL;
836 }
837
838 if (devpoll_flush(self))
839 return NULL;
840
841 dvp.dp_fds = self->fds;
842 dvp.dp_nfds = self->max_n_fds;
843 dvp.dp_timeout = timeout;
844
845 /* call devpoll() */
846 Py_BEGIN_ALLOW_THREADS
847 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
848 Py_END_ALLOW_THREADS
849
850 if (poll_result < 0) {
851 PyErr_SetFromErrno(PyExc_IOError);
852 return NULL;
853 }
854
855 /* build the result list */
856
857 result_list = PyList_New(poll_result);
858 if (!result_list)
859 return NULL;
860 else {
861 for (i = 0; i < poll_result; i++) {
862 num1 = PyLong_FromLong(self->fds[i].fd);
863 num2 = PyLong_FromLong(self->fds[i].revents);
864 if ((num1 == NULL) || (num2 == NULL)) {
865 Py_XDECREF(num1);
866 Py_XDECREF(num2);
867 goto error;
868 }
869 value = PyTuple_Pack(2, num1, num2);
870 Py_DECREF(num1);
871 Py_DECREF(num2);
872 if (value == NULL)
873 goto error;
874 if ((PyList_SetItem(result_list, i, value)) == -1) {
875 Py_DECREF(value);
876 goto error;
877 }
878 }
879 }
880
881 return result_list;
882
883 error:
884 Py_DECREF(result_list);
885 return NULL;
886}
887
888static PyMethodDef devpoll_methods[] = {
889 {"register", (PyCFunction)devpoll_register,
890 METH_VARARGS, devpoll_register_doc},
891 {"modify", (PyCFunction)devpoll_modify,
892 METH_VARARGS, devpoll_modify_doc},
893 {"unregister", (PyCFunction)devpoll_unregister,
894 METH_O, devpoll_unregister_doc},
895 {"poll", (PyCFunction)devpoll_poll,
896 METH_VARARGS, devpoll_poll_doc},
897 {NULL, NULL} /* sentinel */
898};
899
900static devpollObject *
901newDevPollObject(void)
902{
903 devpollObject *self;
904 int fd_devpoll, limit_result;
905 struct pollfd *fds;
906 struct rlimit limit;
907
908 Py_BEGIN_ALLOW_THREADS
909 /*
910 ** If we try to process more that getrlimit()
911 ** fds, the kernel will give an error, so
912 ** we set the limit here. It is a dynamic
913 ** value, because we can change rlimit() anytime.
914 */
915 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
916 if (limit_result != -1)
917 fd_devpoll = open("/dev/poll", O_RDWR);
918 Py_END_ALLOW_THREADS
919
920 if (limit_result == -1) {
921 PyErr_SetFromErrno(PyExc_OSError);
922 return NULL;
923 }
924 if (fd_devpoll == -1) {
925 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
926 return NULL;
927 }
928
929 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
930 if (fds == NULL) {
931 close(fd_devpoll);
932 PyErr_NoMemory();
933 return NULL;
934 }
935
936 self = PyObject_New(devpollObject, &devpoll_Type);
937 if (self == NULL) {
938 close(fd_devpoll);
939 PyMem_DEL(fds);
940 return NULL;
941 }
942 self->fd_devpoll = fd_devpoll;
943 self->max_n_fds = limit.rlim_cur;
944 self->n_fds = 0;
945 self->fds = fds;
946
947 return self;
948}
949
950static void
951devpoll_dealloc(devpollObject *self)
952{
953 Py_BEGIN_ALLOW_THREADS
954 close(self->fd_devpoll);
955 Py_END_ALLOW_THREADS
956
957 PyMem_DEL(self->fds);
958
959 PyObject_Del(self);
960}
961
962static PyTypeObject devpoll_Type = {
963 /* The ob_type field must be initialized in the module init function
964 * to be portable to Windows without using C++. */
965 PyVarObject_HEAD_INIT(NULL, 0)
966 "select.devpoll", /*tp_name*/
967 sizeof(devpollObject), /*tp_basicsize*/
968 0, /*tp_itemsize*/
969 /* methods */
970 (destructor)devpoll_dealloc, /*tp_dealloc*/
971 0, /*tp_print*/
972 0, /*tp_getattr*/
973 0, /*tp_setattr*/
974 0, /*tp_reserved*/
975 0, /*tp_repr*/
976 0, /*tp_as_number*/
977 0, /*tp_as_sequence*/
978 0, /*tp_as_mapping*/
979 0, /*tp_hash*/
980 0, /*tp_call*/
981 0, /*tp_str*/
982 0, /*tp_getattro*/
983 0, /*tp_setattro*/
984 0, /*tp_as_buffer*/
985 Py_TPFLAGS_DEFAULT, /*tp_flags*/
986 0, /*tp_doc*/
987 0, /*tp_traverse*/
988 0, /*tp_clear*/
989 0, /*tp_richcompare*/
990 0, /*tp_weaklistoffset*/
991 0, /*tp_iter*/
992 0, /*tp_iternext*/
993 devpoll_methods, /*tp_methods*/
994};
995#endif /* HAVE_SYS_DEVPOLL_H */
996
997
998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000999PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001000"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001001unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001002
1003static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001004select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001007}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001008
Jesus Cead8b9ae62011-11-14 19:07:41 +01001009#ifdef HAVE_SYS_DEVPOLL_H
1010PyDoc_STRVAR(devpoll_doc,
1011"Returns a polling object, which supports registering and\n\
1012unregistering file descriptors, and then polling them for I/O events.");
1013
1014static PyObject *
1015select_devpoll(PyObject *self, PyObject *unused)
1016{
1017 return (PyObject *)newDevPollObject();
1018}
1019#endif
1020
1021
Thomas Wouters477c8d52006-05-27 19:21:47 +00001022#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001024 * On some systems poll() sets errno on invalid file descriptors. We test
1025 * for this at runtime because this bug may be fixed or introduced between
1026 * OS releases.
1027 */
1028static int select_have_broken_poll(void)
1029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 int poll_test;
1031 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 /* Create a file descriptor to make invalid */
1036 if (pipe(filedes) < 0) {
1037 return 1;
1038 }
1039 poll_struct.fd = filedes[0];
1040 close(filedes[0]);
1041 close(filedes[1]);
1042 poll_test = poll(&poll_struct, 1, 0);
1043 if (poll_test < 0) {
1044 return 1;
1045 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1046 return 1;
1047 }
1048 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001049}
1050#endif /* __APPLE__ */
1051
1052#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001053
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001054#ifdef HAVE_EPOLL
1055/* **************************************************************************
1056 * epoll interface for Linux 2.6
1057 *
1058 * Written by Christian Heimes
1059 * Inspired by Twisted's _epoll.pyx and select.poll()
1060 */
1061
1062#ifdef HAVE_SYS_EPOLL_H
1063#include <sys/epoll.h>
1064#endif
1065
1066typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 PyObject_HEAD
1068 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001069} pyEpoll_Object;
1070
1071static PyTypeObject pyEpoll_Type;
1072#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1073
1074static PyObject *
1075pyepoll_err_closed(void)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1078 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001079}
1080
1081static int
1082pyepoll_internal_close(pyEpoll_Object *self)
1083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 int save_errno = 0;
1085 if (self->epfd >= 0) {
1086 int epfd = self->epfd;
1087 self->epfd = -1;
1088 Py_BEGIN_ALLOW_THREADS
1089 if (close(epfd) < 0)
1090 save_errno = errno;
1091 Py_END_ALLOW_THREADS
1092 }
1093 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001094}
1095
1096static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001097newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 assert(type != NULL && type->tp_alloc != NULL);
1102 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1103 if (self == NULL)
1104 return NULL;
1105
1106 if (fd == -1) {
1107 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001108#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001109 if (flags)
1110 self->epfd = epoll_create1(flags);
1111 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001112#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001113 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_END_ALLOW_THREADS
1115 }
1116 else {
1117 self->epfd = fd;
1118 }
1119 if (self->epfd < 0) {
1120 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001121 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 return NULL;
1123 }
1124 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001125}
1126
1127
1128static PyObject *
1129pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1130{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001131 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001132 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001133
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001134 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1135 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001137 if (sizehint < 0) {
1138 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1139 return NULL;
1140 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001141
Benjamin Peterson95c16622011-12-27 15:36:32 -06001142 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001143}
1144
1145
1146static void
1147pyepoll_dealloc(pyEpoll_Object *self)
1148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 (void)pyepoll_internal_close(self);
1150 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001151}
1152
1153static PyObject*
1154pyepoll_close(pyEpoll_Object *self)
1155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 errno = pyepoll_internal_close(self);
1157 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001158 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 return NULL;
1160 }
1161 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001162}
1163
1164PyDoc_STRVAR(pyepoll_close_doc,
1165"close() -> None\n\
1166\n\
1167Close the epoll control file descriptor. Further operations on the epoll\n\
1168object will raise an exception.");
1169
1170static PyObject*
1171pyepoll_get_closed(pyEpoll_Object *self)
1172{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 if (self->epfd < 0)
1174 Py_RETURN_TRUE;
1175 else
1176 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001177}
1178
1179static PyObject*
1180pyepoll_fileno(pyEpoll_Object *self)
1181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 if (self->epfd < 0)
1183 return pyepoll_err_closed();
1184 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001185}
1186
1187PyDoc_STRVAR(pyepoll_fileno_doc,
1188"fileno() -> int\n\
1189\n\
1190Return the epoll control file descriptor.");
1191
1192static PyObject*
1193pyepoll_fromfd(PyObject *cls, PyObject *args)
1194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1198 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001199
Benjamin Peterson95c16622011-12-27 15:36:32 -06001200 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001201}
1202
1203PyDoc_STRVAR(pyepoll_fromfd_doc,
1204"fromfd(fd) -> epoll\n\
1205\n\
1206Create an epoll object from a given control fd.");
1207
1208static PyObject *
1209pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1210{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 struct epoll_event ev;
1212 int result;
1213 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 if (epfd < 0)
1216 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 fd = PyObject_AsFileDescriptor(pfd);
1219 if (fd == -1) {
1220 return NULL;
1221 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 switch(op) {
1224 case EPOLL_CTL_ADD:
1225 case EPOLL_CTL_MOD:
1226 ev.events = events;
1227 ev.data.fd = fd;
1228 Py_BEGIN_ALLOW_THREADS
1229 result = epoll_ctl(epfd, op, fd, &ev);
1230 Py_END_ALLOW_THREADS
1231 break;
1232 case EPOLL_CTL_DEL:
1233 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1234 * operation required a non-NULL pointer in event, even
1235 * though this argument is ignored. */
1236 Py_BEGIN_ALLOW_THREADS
1237 result = epoll_ctl(epfd, op, fd, &ev);
1238 if (errno == EBADF) {
1239 /* fd already closed */
1240 result = 0;
1241 errno = 0;
1242 }
1243 Py_END_ALLOW_THREADS
1244 break;
1245 default:
1246 result = -1;
1247 errno = EINVAL;
1248 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001251 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 return NULL;
1253 }
1254 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001255}
1256
1257static PyObject *
1258pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 PyObject *pfd;
1261 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1262 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1265 &pfd, &events)) {
1266 return NULL;
1267 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001270}
1271
1272PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001273"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001274\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001275Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001276fd is the target file descriptor of the operation.\n\
1277events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001278is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1279\n\
1280The epoll interface supports all file descriptors that support poll.");
1281
1282static PyObject *
1283pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 PyObject *pfd;
1286 unsigned int events;
1287 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1290 &pfd, &events)) {
1291 return NULL;
1292 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001295}
1296
1297PyDoc_STRVAR(pyepoll_modify_doc,
1298"modify(fd, eventmask) -> None\n\
1299\n\
1300fd is the target file descriptor of the operation\n\
1301events is a bit set composed of the various EPOLL constants");
1302
1303static PyObject *
1304pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 PyObject *pfd;
1307 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1310 &pfd)) {
1311 return NULL;
1312 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001315}
1316
1317PyDoc_STRVAR(pyepoll_unregister_doc,
1318"unregister(fd) -> None\n\
1319\n\
1320fd is the target file descriptor of the operation.");
1321
1322static PyObject *
1323pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 double dtimeout = -1.;
1326 int timeout;
1327 int maxevents = -1;
1328 int nfds, i;
1329 PyObject *elist = NULL, *etuple = NULL;
1330 struct epoll_event *evs = NULL;
1331 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (self->epfd < 0)
1334 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1337 &dtimeout, &maxevents)) {
1338 return NULL;
1339 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 if (dtimeout < 0) {
1342 timeout = -1;
1343 }
1344 else if (dtimeout * 1000.0 > INT_MAX) {
1345 PyErr_SetString(PyExc_OverflowError,
1346 "timeout is too large");
1347 return NULL;
1348 }
1349 else {
1350 timeout = (int)(dtimeout * 1000.0);
1351 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 if (maxevents == -1) {
1354 maxevents = FD_SETSIZE-1;
1355 }
1356 else if (maxevents < 1) {
1357 PyErr_Format(PyExc_ValueError,
1358 "maxevents must be greater than 0, got %d",
1359 maxevents);
1360 return NULL;
1361 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 evs = PyMem_New(struct epoll_event, maxevents);
1364 if (evs == NULL) {
1365 Py_DECREF(self);
1366 PyErr_NoMemory();
1367 return NULL;
1368 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 Py_BEGIN_ALLOW_THREADS
1371 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1372 Py_END_ALLOW_THREADS
1373 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001374 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 goto error;
1376 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 elist = PyList_New(nfds);
1379 if (elist == NULL) {
1380 goto error;
1381 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 for (i = 0; i < nfds; i++) {
1384 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1385 if (etuple == NULL) {
1386 Py_CLEAR(elist);
1387 goto error;
1388 }
1389 PyList_SET_ITEM(elist, i, etuple);
1390 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001391
Christian Heimesf6cd9672008-03-26 13:45:42 +00001392 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 PyMem_Free(evs);
1394 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001395}
1396
1397PyDoc_STRVAR(pyepoll_poll_doc,
1398"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1399\n\
1400Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1401in seconds (as float). -1 makes poll wait indefinitely.\n\
1402Up to maxevents are returned to the caller.");
1403
1404static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 {"fromfd", (PyCFunction)pyepoll_fromfd,
1406 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1407 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1408 pyepoll_close_doc},
1409 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1410 pyepoll_fileno_doc},
1411 {"modify", (PyCFunction)pyepoll_modify,
1412 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1413 {"register", (PyCFunction)pyepoll_register,
1414 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1415 {"unregister", (PyCFunction)pyepoll_unregister,
1416 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1417 {"poll", (PyCFunction)pyepoll_poll,
1418 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1419 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001420};
1421
1422static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 {"closed", (getter)pyepoll_get_closed, NULL,
1424 "True if the epoll handler is closed"},
1425 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001426};
1427
1428PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001429"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001430\n\
1431Returns an epolling object\n\
1432\n\
1433sizehint must be a positive integer or -1 for the default size. The\n\
1434sizehint is used to optimize internal data structures. It doesn't limit\n\
1435the maximum number of monitored events.");
1436
1437static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 PyVarObject_HEAD_INIT(NULL, 0)
1439 "select.epoll", /* tp_name */
1440 sizeof(pyEpoll_Object), /* tp_basicsize */
1441 0, /* tp_itemsize */
1442 (destructor)pyepoll_dealloc, /* tp_dealloc */
1443 0, /* tp_print */
1444 0, /* tp_getattr */
1445 0, /* tp_setattr */
1446 0, /* tp_reserved */
1447 0, /* tp_repr */
1448 0, /* tp_as_number */
1449 0, /* tp_as_sequence */
1450 0, /* tp_as_mapping */
1451 0, /* tp_hash */
1452 0, /* tp_call */
1453 0, /* tp_str */
1454 PyObject_GenericGetAttr, /* tp_getattro */
1455 0, /* tp_setattro */
1456 0, /* tp_as_buffer */
1457 Py_TPFLAGS_DEFAULT, /* tp_flags */
1458 pyepoll_doc, /* tp_doc */
1459 0, /* tp_traverse */
1460 0, /* tp_clear */
1461 0, /* tp_richcompare */
1462 0, /* tp_weaklistoffset */
1463 0, /* tp_iter */
1464 0, /* tp_iternext */
1465 pyepoll_methods, /* tp_methods */
1466 0, /* tp_members */
1467 pyepoll_getsetlist, /* tp_getset */
1468 0, /* tp_base */
1469 0, /* tp_dict */
1470 0, /* tp_descr_get */
1471 0, /* tp_descr_set */
1472 0, /* tp_dictoffset */
1473 0, /* tp_init */
1474 0, /* tp_alloc */
1475 pyepoll_new, /* tp_new */
1476 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001477};
1478
1479#endif /* HAVE_EPOLL */
1480
1481#ifdef HAVE_KQUEUE
1482/* **************************************************************************
1483 * kqueue interface for BSD
1484 *
1485 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1486 * All rights reserved.
1487 *
1488 * Redistribution and use in source and binary forms, with or without
1489 * modification, are permitted provided that the following conditions
1490 * are met:
1491 * 1. Redistributions of source code must retain the above copyright
1492 * notice, this list of conditions and the following disclaimer.
1493 * 2. Redistributions in binary form must reproduce the above copyright
1494 * notice, this list of conditions and the following disclaimer in the
1495 * documentation and/or other materials provided with the distribution.
1496 *
1497 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1498 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1499 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1500 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1501 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1502 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1503 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1504 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1505 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1506 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1507 * SUCH DAMAGE.
1508 */
1509
1510#ifdef HAVE_SYS_EVENT_H
1511#include <sys/event.h>
1512#endif
1513
1514PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001515"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001516\n\
1517This object is the equivalent of the struct kevent for the C API.\n\
1518\n\
1519See the kqueue manpage for more detailed information about the meaning\n\
1520of the arguments.\n\
1521\n\
1522One minor note: while you might hope that udata could store a\n\
1523reference to a python object, it cannot, because it is impossible to\n\
1524keep a proper reference count of the object once it's passed into the\n\
1525kernel. Therefore, I have restricted it to only storing an integer. I\n\
1526recommend ignoring it and simply using the 'ident' field to key off\n\
1527of. You could also set up a dictionary on the python side to store a\n\
1528udata->object mapping.");
1529
1530typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 PyObject_HEAD
1532 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001533} kqueue_event_Object;
1534
1535static PyTypeObject kqueue_event_Type;
1536
1537#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1538
1539typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 PyObject_HEAD
1541 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001542} kqueue_queue_Object;
1543
1544static PyTypeObject kqueue_queue_Type;
1545
1546#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1547
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001548#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1549# error uintptr_t does not match void *!
1550#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1551# define T_UINTPTRT T_ULONGLONG
1552# define T_INTPTRT T_LONGLONG
1553# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1554# define UINTPTRT_FMT_UNIT "K"
1555# define INTPTRT_FMT_UNIT "L"
1556#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1557# define T_UINTPTRT T_ULONG
1558# define T_INTPTRT T_LONG
1559# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1560# define UINTPTRT_FMT_UNIT "k"
1561# define INTPTRT_FMT_UNIT "l"
1562#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1563# define T_UINTPTRT T_UINT
1564# define T_INTPTRT T_INT
1565# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1566# define UINTPTRT_FMT_UNIT "I"
1567# define INTPTRT_FMT_UNIT "i"
1568#else
1569# error uintptr_t does not match int, long, or long long!
1570#endif
1571
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001572/* Unfortunately, we can't store python objects in udata, because
1573 * kevents in the kernel can be removed without warning, which would
1574 * forever lose the refcount on the object stored with it.
1575 */
1576
1577#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1578static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1580 {"filter", T_SHORT, KQ_OFF(e.filter)},
1581 {"flags", T_USHORT, KQ_OFF(e.flags)},
1582 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1583 {"data", T_INTPTRT, KQ_OFF(e.data)},
1584 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1585 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001586};
1587#undef KQ_OFF
1588
1589static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001590
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001591kqueue_event_repr(kqueue_event_Object *s)
1592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 char buf[1024];
1594 PyOS_snprintf(
1595 buf, sizeof(buf),
1596 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1597 "data=0x%zd udata=%p>",
1598 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1599 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1600 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601}
1602
1603static int
1604kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 PyObject *pfd;
1607 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1608 "data", "udata", NULL};
1609 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1614 &pfd, &(self->e.filter), &(self->e.flags),
1615 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1616 return -1;
1617 }
1618
1619 if (PyLong_Check(pfd)) {
1620 self->e.ident = PyLong_AsUintptr_t(pfd);
1621 }
1622 else {
1623 self->e.ident = PyObject_AsFileDescriptor(pfd);
1624 }
1625 if (PyErr_Occurred()) {
1626 return -1;
1627 }
1628 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001629}
1630
1631static PyObject *
1632kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 if (!kqueue_event_Check(o)) {
1638 if (op == Py_EQ || op == Py_NE) {
1639 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1640 Py_INCREF(res);
1641 return res;
1642 }
1643 PyErr_Format(PyExc_TypeError,
1644 "can't compare %.200s to %.200s",
1645 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1646 return NULL;
1647 }
1648 if (((result = s->e.ident - o->e.ident) == 0) &&
1649 ((result = s->e.filter - o->e.filter) == 0) &&
1650 ((result = s->e.flags - o->e.flags) == 0) &&
1651 ((result = s->e.fflags - o->e.fflags) == 0) &&
1652 ((result = s->e.data - o->e.data) == 0) &&
1653 ((result = s->e.udata - o->e.udata) == 0)
1654 ) {
1655 result = 0;
1656 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 switch (op) {
1659 case Py_EQ:
1660 result = (result == 0);
1661 break;
1662 case Py_NE:
1663 result = (result != 0);
1664 break;
1665 case Py_LE:
1666 result = (result <= 0);
1667 break;
1668 case Py_GE:
1669 result = (result >= 0);
1670 break;
1671 case Py_LT:
1672 result = (result < 0);
1673 break;
1674 case Py_GT:
1675 result = (result > 0);
1676 break;
1677 }
1678 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001679}
1680
1681static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 PyVarObject_HEAD_INIT(NULL, 0)
1683 "select.kevent", /* tp_name */
1684 sizeof(kqueue_event_Object), /* tp_basicsize */
1685 0, /* tp_itemsize */
1686 0, /* tp_dealloc */
1687 0, /* tp_print */
1688 0, /* tp_getattr */
1689 0, /* tp_setattr */
1690 0, /* tp_reserved */
1691 (reprfunc)kqueue_event_repr, /* tp_repr */
1692 0, /* tp_as_number */
1693 0, /* tp_as_sequence */
1694 0, /* tp_as_mapping */
1695 0, /* tp_hash */
1696 0, /* tp_call */
1697 0, /* tp_str */
1698 0, /* tp_getattro */
1699 0, /* tp_setattro */
1700 0, /* tp_as_buffer */
1701 Py_TPFLAGS_DEFAULT, /* tp_flags */
1702 kqueue_event_doc, /* tp_doc */
1703 0, /* tp_traverse */
1704 0, /* tp_clear */
1705 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1706 0, /* tp_weaklistoffset */
1707 0, /* tp_iter */
1708 0, /* tp_iternext */
1709 0, /* tp_methods */
1710 kqueue_event_members, /* tp_members */
1711 0, /* tp_getset */
1712 0, /* tp_base */
1713 0, /* tp_dict */
1714 0, /* tp_descr_get */
1715 0, /* tp_descr_set */
1716 0, /* tp_dictoffset */
1717 (initproc)kqueue_event_init, /* tp_init */
1718 0, /* tp_alloc */
1719 0, /* tp_new */
1720 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001721};
1722
1723static PyObject *
1724kqueue_queue_err_closed(void)
1725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1727 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001728}
1729
1730static int
1731kqueue_queue_internal_close(kqueue_queue_Object *self)
1732{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733 int save_errno = 0;
1734 if (self->kqfd >= 0) {
1735 int kqfd = self->kqfd;
1736 self->kqfd = -1;
1737 Py_BEGIN_ALLOW_THREADS
1738 if (close(kqfd) < 0)
1739 save_errno = errno;
1740 Py_END_ALLOW_THREADS
1741 }
1742 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001743}
1744
1745static PyObject *
1746newKqueue_Object(PyTypeObject *type, SOCKET fd)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 kqueue_queue_Object *self;
1749 assert(type != NULL && type->tp_alloc != NULL);
1750 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1751 if (self == NULL) {
1752 return NULL;
1753 }
1754
1755 if (fd == -1) {
1756 Py_BEGIN_ALLOW_THREADS
1757 self->kqfd = kqueue();
1758 Py_END_ALLOW_THREADS
1759 }
1760 else {
1761 self->kqfd = fd;
1762 }
1763 if (self->kqfd < 0) {
1764 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001765 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 return NULL;
1767 }
1768 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001769}
1770
1771static PyObject *
1772kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1773{
1774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 if ((args != NULL && PyObject_Size(args)) ||
1776 (kwds != NULL && PyObject_Size(kwds))) {
1777 PyErr_SetString(PyExc_ValueError,
1778 "select.kqueue doesn't accept arguments");
1779 return NULL;
1780 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001783}
1784
1785static void
1786kqueue_queue_dealloc(kqueue_queue_Object *self)
1787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 kqueue_queue_internal_close(self);
1789 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001790}
1791
1792static PyObject*
1793kqueue_queue_close(kqueue_queue_Object *self)
1794{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 errno = kqueue_queue_internal_close(self);
1796 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001797 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 return NULL;
1799 }
1800 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001801}
1802
1803PyDoc_STRVAR(kqueue_queue_close_doc,
1804"close() -> None\n\
1805\n\
1806Close the kqueue control file descriptor. Further operations on the kqueue\n\
1807object will raise an exception.");
1808
1809static PyObject*
1810kqueue_queue_get_closed(kqueue_queue_Object *self)
1811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 if (self->kqfd < 0)
1813 Py_RETURN_TRUE;
1814 else
1815 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001816}
1817
1818static PyObject*
1819kqueue_queue_fileno(kqueue_queue_Object *self)
1820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 if (self->kqfd < 0)
1822 return kqueue_queue_err_closed();
1823 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001824}
1825
1826PyDoc_STRVAR(kqueue_queue_fileno_doc,
1827"fileno() -> int\n\
1828\n\
1829Return the kqueue control file descriptor.");
1830
1831static PyObject*
1832kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1837 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001840}
1841
1842PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1843"fromfd(fd) -> kqueue\n\
1844\n\
1845Create a kqueue object from a given control fd.");
1846
1847static PyObject *
1848kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 int nevents = 0;
1851 int gotevents = 0;
1852 int nchanges = 0;
1853 int i = 0;
1854 PyObject *otimeout = NULL;
1855 PyObject *ch = NULL;
1856 PyObject *it = NULL, *ei = NULL;
1857 PyObject *result = NULL;
1858 struct kevent *evl = NULL;
1859 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001860 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (self->kqfd < 0)
1864 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1867 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 if (nevents < 0) {
1870 PyErr_Format(PyExc_ValueError,
1871 "Length of eventlist must be 0 or positive, got %d",
1872 nevents);
1873 return NULL;
1874 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (otimeout == Py_None || otimeout == NULL) {
1877 ptimeoutspec = NULL;
1878 }
1879 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001880 if (_PyTime_ObjectToTimespec(otimeout,
1881 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1882 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883
Victor Stinner5d272cc2012-03-13 13:35:55 +01001884 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyErr_SetString(PyExc_ValueError,
1886 "timeout must be positive or None");
1887 return NULL;
1888 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001889 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 }
1891 else {
1892 PyErr_Format(PyExc_TypeError,
1893 "timeout argument must be an number "
1894 "or None, got %.200s",
1895 Py_TYPE(otimeout)->tp_name);
1896 return NULL;
1897 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (ch != NULL && ch != Py_None) {
1900 it = PyObject_GetIter(ch);
1901 if (it == NULL) {
1902 PyErr_SetString(PyExc_TypeError,
1903 "changelist is not iterable");
1904 return NULL;
1905 }
1906 nchanges = PyObject_Size(ch);
1907 if (nchanges < 0) {
1908 goto error;
1909 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 chl = PyMem_New(struct kevent, nchanges);
1912 if (chl == NULL) {
1913 PyErr_NoMemory();
1914 goto error;
1915 }
1916 i = 0;
1917 while ((ei = PyIter_Next(it)) != NULL) {
1918 if (!kqueue_event_Check(ei)) {
1919 Py_DECREF(ei);
1920 PyErr_SetString(PyExc_TypeError,
1921 "changelist must be an iterable of "
1922 "select.kevent objects");
1923 goto error;
1924 } else {
1925 chl[i++] = ((kqueue_event_Object *)ei)->e;
1926 }
1927 Py_DECREF(ei);
1928 }
1929 }
1930 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 /* event list */
1933 if (nevents) {
1934 evl = PyMem_New(struct kevent, nevents);
1935 if (evl == NULL) {
1936 PyErr_NoMemory();
1937 goto error;
1938 }
1939 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 Py_BEGIN_ALLOW_THREADS
1942 gotevents = kevent(self->kqfd, chl, nchanges,
1943 evl, nevents, ptimeoutspec);
1944 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 if (gotevents == -1) {
1947 PyErr_SetFromErrno(PyExc_OSError);
1948 goto error;
1949 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 result = PyList_New(gotevents);
1952 if (result == NULL) {
1953 goto error;
1954 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 for (i = 0; i < gotevents; i++) {
1957 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1960 if (ch == NULL) {
1961 goto error;
1962 }
1963 ch->e = evl[i];
1964 PyList_SET_ITEM(result, i, (PyObject *)ch);
1965 }
1966 PyMem_Free(chl);
1967 PyMem_Free(evl);
1968 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001969
1970 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 PyMem_Free(chl);
1972 PyMem_Free(evl);
1973 Py_XDECREF(result);
1974 Py_XDECREF(it);
1975 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001976}
1977
1978PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001979"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001980\n\
1981Calls the kernel kevent function.\n\
1982- changelist must be a list of kevent objects describing the changes\n\
1983 to be made to the kernel's watch list or None.\n\
1984- max_events lets you specify the maximum number of events that the\n\
1985 kernel will return.\n\
1986- timeout is the maximum time to wait in seconds, or else None,\n\
1987 to wait forever. timeout accepts floats for smaller timeouts, too.");
1988
1989
1990static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1992 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1993 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1994 kqueue_queue_close_doc},
1995 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1996 kqueue_queue_fileno_doc},
1997 {"control", (PyCFunction)kqueue_queue_control,
1998 METH_VARARGS , kqueue_queue_control_doc},
1999 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002000};
2001
2002static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 {"closed", (getter)kqueue_queue_get_closed, NULL,
2004 "True if the kqueue handler is closed"},
2005 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002006};
2007
2008PyDoc_STRVAR(kqueue_queue_doc,
2009"Kqueue syscall wrapper.\n\
2010\n\
2011For example, to start watching a socket for input:\n\
2012>>> kq = kqueue()\n\
2013>>> sock = socket()\n\
2014>>> sock.connect((host, port))\n\
2015>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2016\n\
2017To wait one second for it to become writeable:\n\
2018>>> kq.control(None, 1, 1000)\n\
2019\n\
2020To stop listening:\n\
2021>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2022
2023static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 PyVarObject_HEAD_INIT(NULL, 0)
2025 "select.kqueue", /* tp_name */
2026 sizeof(kqueue_queue_Object), /* tp_basicsize */
2027 0, /* tp_itemsize */
2028 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2029 0, /* tp_print */
2030 0, /* tp_getattr */
2031 0, /* tp_setattr */
2032 0, /* tp_reserved */
2033 0, /* tp_repr */
2034 0, /* tp_as_number */
2035 0, /* tp_as_sequence */
2036 0, /* tp_as_mapping */
2037 0, /* tp_hash */
2038 0, /* tp_call */
2039 0, /* tp_str */
2040 0, /* tp_getattro */
2041 0, /* tp_setattro */
2042 0, /* tp_as_buffer */
2043 Py_TPFLAGS_DEFAULT, /* tp_flags */
2044 kqueue_queue_doc, /* tp_doc */
2045 0, /* tp_traverse */
2046 0, /* tp_clear */
2047 0, /* tp_richcompare */
2048 0, /* tp_weaklistoffset */
2049 0, /* tp_iter */
2050 0, /* tp_iternext */
2051 kqueue_queue_methods, /* tp_methods */
2052 0, /* tp_members */
2053 kqueue_queue_getsetlist, /* tp_getset */
2054 0, /* tp_base */
2055 0, /* tp_dict */
2056 0, /* tp_descr_get */
2057 0, /* tp_descr_set */
2058 0, /* tp_dictoffset */
2059 0, /* tp_init */
2060 0, /* tp_alloc */
2061 kqueue_queue_new, /* tp_new */
2062 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002063};
2064
2065#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002066
2067
2068
2069
2070
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002071/* ************************************************************************ */
2072
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002074"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2075\n\
2076Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002077The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002078rlist -- wait until ready for reading\n\
2079wlist -- wait until ready for writing\n\
2080xlist -- wait for an ``exceptional condition''\n\
2081If only one kind of condition is required, pass [] for the other lists.\n\
2082A file descriptor is either a socket or file object, or a small integer\n\
2083gotten from a fileno() method call on one of those.\n\
2084\n\
2085The optional 4th argument specifies a timeout in seconds; it may be\n\
2086a floating point number to specify fractions of seconds. If it is absent\n\
2087or None, the call will never time out.\n\
2088\n\
2089The return value is a tuple of three lists corresponding to the first three\n\
2090arguments; each contains the subset of the corresponding file descriptors\n\
2091that are ready.\n\
2092\n\
2093*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002094On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002095descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002096
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002097static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002099#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002101#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002102#ifdef HAVE_SYS_DEVPOLL_H
2103 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2104#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002106};
2107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002109"This module supports asynchronous I/O on multiple file descriptors.\n\
2110\n\
2111*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002112On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002113
Martin v. Löwis1a214512008-06-11 05:26:20 +00002114
2115static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 PyModuleDef_HEAD_INIT,
2117 "select",
2118 module_doc,
2119 -1,
2120 select_methods,
2121 NULL,
2122 NULL,
2123 NULL,
2124 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002125};
2126
Jesus Cead8b9ae62011-11-14 19:07:41 +01002127
2128
2129
Mark Hammond62b1ab12002-07-23 06:31:15 +00002130PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002131PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 PyObject *m;
2134 m = PyModule_Create(&selectmodule);
2135 if (m == NULL)
2136 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002137
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002138 Py_INCREF(PyExc_OSError);
2139 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002140
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002141#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002142#ifdef HAVE_BROKEN_PIPE_BUF
2143#undef PIPE_BUF
2144#define PIPE_BUF 512
2145#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002147#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002148
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002149#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002150#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (select_have_broken_poll()) {
2152 if (PyObject_DelAttrString(m, "poll") == -1) {
2153 PyErr_Clear();
2154 }
2155 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002156#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002158#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 if (PyType_Ready(&poll_Type) < 0)
2160 return NULL;
2161 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2162 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2163 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2164 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2165 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2166 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002167
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002168#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002170#endif
2171#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002173#endif
2174#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002176#endif
2177#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002179#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002180#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002182#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002184#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002185
Jesus Cead8b9ae62011-11-14 19:07:41 +01002186#ifdef HAVE_SYS_DEVPOLL_H
2187 if (PyType_Ready(&devpoll_Type) < 0)
2188 return NULL;
2189#endif
2190
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002191#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2193 if (PyType_Ready(&pyEpoll_Type) < 0)
2194 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 Py_INCREF(&pyEpoll_Type);
2197 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2200 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2201 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2202 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2203 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2204 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002205#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 /* Kernel 2.6.2+ */
2207 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002208#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2210 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2211 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2212 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2213 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2214 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002215
Benjamin Peterson95c16622011-12-27 15:36:32 -06002216#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002217 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002218#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002219#endif /* HAVE_EPOLL */
2220
2221#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 kqueue_event_Type.tp_new = PyType_GenericNew;
2223 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2224 if(PyType_Ready(&kqueue_event_Type) < 0)
2225 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 Py_INCREF(&kqueue_event_Type);
2228 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2231 if(PyType_Ready(&kqueue_queue_Type) < 0)
2232 return NULL;
2233 Py_INCREF(&kqueue_queue_Type);
2234 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2235
2236 /* event filters */
2237 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2238 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2239 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2240 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2241 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2246 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 /* event flags */
2249 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2250 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2251 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2252 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2253 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2254 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2257 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2260 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 /* READ WRITE filter flag */
2263 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 /* VNODE filter flags */
2266 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2267 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2268 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2269 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2272 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 /* PROC filter flags */
2275 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2276 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2277 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2278 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2279 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2282 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2283 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2284
2285 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002286#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2288 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2289 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002290#endif
2291
2292#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002294}