blob: 52be4d8eea09cda25d0f025ead0d1557517a34e1 [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
Guido van Rossum6f489d91996-06-28 20:15:15 +000050#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000051# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000055# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <socket.h>
57# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000058#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000059
Barry Warsawc1cb3601996-12-12 22:16:21 +000060/* list of Python objects and their file descriptor */
61typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 PyObject *obj; /* owned reference */
63 SOCKET fd;
64 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000065} pylist;
66
Barry Warsawc1cb3601996-12-12 22:16:21 +000067static void
Tim Peters4b046c22001-08-16 21:59:46 +000068reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 int i;
71 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
72 Py_XDECREF(fd2obj[i].obj);
73 fd2obj[i].obj = NULL;
74 }
75 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000076}
77
78
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000079/* returns -1 and sets the Python exception if an error occurred, otherwise
80 returns a number >= 0
81*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000082static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000083seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 int max = -1;
86 int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010087 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 PyObject* fast_seq = NULL;
89 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
92 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000094 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (!fast_seq)
96 return -1;
97
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010098 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 SOCKET v;
100
101 /* any intervening fileno() calls could decr this refcnt */
102 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200103 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 Py_INCREF(o);
106 v = PyObject_AsFileDescriptor( o );
107 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000108
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000109#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000111#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200112 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 PyErr_SetString(PyExc_ValueError,
114 "filedescriptor out of range in select()");
115 goto finally;
116 }
117 if (v > max)
118 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 /* add object and its file descriptor to the list */
123 if (index >= FD_SETSIZE) {
124 PyErr_SetString(PyExc_ValueError,
125 "too many file descriptors in select()");
126 goto finally;
127 }
128 fd2obj[index].obj = o;
129 fd2obj[index].fd = v;
130 fd2obj[index].sentinel = 0;
131 fd2obj[++index].sentinel = -1;
132 }
133 Py_DECREF(fast_seq);
134 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135
136 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 Py_XDECREF(o);
138 Py_DECREF(fast_seq);
139 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000140}
141
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000142/* returns NULL and sets the Python exception if an error occurred */
143static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 int i, j, count=0;
147 PyObject *list, *o;
148 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
151 if (FD_ISSET(fd2obj[j].fd, set))
152 count++;
153 }
154 list = PyList_New(count);
155 if (!list)
156 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 i = 0;
159 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
160 fd = fd2obj[j].fd;
161 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 o = fd2obj[j].obj;
163 fd2obj[j].obj = NULL;
164 /* transfer ownership */
165 if (PyList_SetItem(list, i, o) < 0)
166 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 i++;
169 }
170 }
171 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 Py_DECREF(list);
174 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000175}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000176
Barry Warsawb44740f2001-08-16 16:52:59 +0000177#undef SELECT_USES_HEAP
178#if FD_SETSIZE > 1024
179#define SELECT_USES_HEAP
180#endif /* FD_SETSIZE > 1024 */
181
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000182static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000183select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000184{
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 /* XXX: All this should probably be implemented as follows:
189 * - find the highest descriptor we're interested in
190 * - add one
191 * - that's the size
192 * See: Stevens, APitUE, $12.5.1
193 */
194 pylist rfd2obj[FD_SETSIZE + 1];
195 pylist wfd2obj[FD_SETSIZE + 1];
196 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000197#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 PyObject *ifdlist, *ofdlist, *efdlist;
199 PyObject *ret = NULL;
200 PyObject *tout = Py_None;
201 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 int imax, omax, emax, max;
204 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 /* convert arguments */
207 if (!PyArg_UnpackTuple(args, "select", 3, 4,
208 &ifdlist, &ofdlist, &efdlist, &tout))
209 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 if (tout == Py_None)
212 tvp = (struct timeval *)0;
213 else if (!PyNumber_Check(tout)) {
214 PyErr_SetString(PyExc_TypeError,
215 "timeout must be a float or None");
216 return NULL;
217 }
218 else {
Victor Stinnerb2a37732012-03-14 00:20:51 +0100219#ifdef MS_WINDOWS
220 time_t sec;
221 if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 return NULL;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100223 assert(sizeof(tv.tv_sec) == sizeof(long));
224#if SIZEOF_TIME_T > SIZEOF_LONG
225 if (sec > LONG_MAX) {
226 PyErr_SetString(PyExc_OverflowError,
227 "timeout is too large");
228 return NULL;
229 }
230#endif
231 tv.tv_sec = (long)sec;
232#else
Brett Cannon8798ad32012-04-07 14:59:29 -0400233 /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4
234 bytes as required), but no longer defined by a long. */
Benjamin Peterson6f3e5e42012-09-11 12:05:05 -0400235 long tv_usec;
Brett Cannon8798ad32012-04-07 14:59:29 -0400236 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1)
Victor Stinnerb2a37732012-03-14 00:20:51 +0100237 return NULL;
Brett Cannon8798ad32012-04-07 14:59:29 -0400238 tv.tv_usec = tv_usec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100239#endif
Victor Stinner5d272cc2012-03-13 13:35:55 +0100240 if (tv.tv_sec < 0) {
241 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 return NULL;
243 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 tvp = &tv;
245 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000246
Guido van Rossumed233a51992-06-23 09:07:03 +0000247
Barry Warsawb44740f2001-08-16 16:52:59 +0000248#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 /* Allocate memory for the lists */
250 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
251 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
254 if (rfd2obj) PyMem_DEL(rfd2obj);
255 if (wfd2obj) PyMem_DEL(wfd2obj);
256 if (efd2obj) PyMem_DEL(efd2obj);
257 return PyErr_NoMemory();
258 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000259#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 /* Convert sequences to fd_sets, and get maximum fd number
261 * propagates the Python exception set in seq2set()
262 */
263 rfd2obj[0].sentinel = -1;
264 wfd2obj[0].sentinel = -1;
265 efd2obj[0].sentinel = -1;
266 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
267 goto finally;
268 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
269 goto finally;
270 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
271 goto finally;
272 max = imax;
273 if (omax > max) max = omax;
274 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 Py_BEGIN_ALLOW_THREADS
277 n = select(max, &ifdset, &ofdset, &efdset, tvp);
278 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000279
Thomas Heller106f4c72002-09-24 16:51:00 +0000280#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200282 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000284#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200286 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000288#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 else {
290 /* any of these three calls can raise an exception. it's more
291 convenient to test for this after all three calls... but
292 is that acceptable?
293 */
294 ifdlist = set2list(&ifdset, rfd2obj);
295 ofdlist = set2list(&ofdset, wfd2obj);
296 efdlist = set2list(&efdset, efd2obj);
297 if (PyErr_Occurred())
298 ret = NULL;
299 else
300 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 Py_DECREF(ifdlist);
303 Py_DECREF(ofdlist);
304 Py_DECREF(efdlist);
305 }
306
Barry Warsawc1cb3601996-12-12 22:16:21 +0000307 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 reap_obj(rfd2obj);
309 reap_obj(wfd2obj);
310 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000311#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 PyMem_DEL(rfd2obj);
313 PyMem_DEL(wfd2obj);
314 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000315#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000317}
318
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000319#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000321 * poll() support
322 */
323
324typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 PyObject_HEAD
326 PyObject *dict;
327 int ufd_uptodate;
328 int ufd_len;
329 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000330} pollObject;
331
Jeremy Hylton938ace62002-07-17 16:30:39 +0000332static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335 contained within a pollObject. Return 1 on success, 0 on an error.
336*/
337
338static int
339update_ufd_array(pollObject *self)
340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 Py_ssize_t i, pos;
342 PyObject *key, *value;
343 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 self->ufd_len = PyDict_Size(self->dict);
346 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
347 if (self->ufds == NULL) {
348 self->ufds = old_ufds;
349 PyErr_NoMemory();
350 return 0;
351 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 i = pos = 0;
354 while (PyDict_Next(self->dict, &pos, &key, &value)) {
355 self->ufds[i].fd = PyLong_AsLong(key);
356 self->ufds[i].events = (short)PyLong_AsLong(value);
357 i++;
358 }
359 self->ufd_uptodate = 1;
360 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000361}
362
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000363PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000364"register(fd [, eventmask] ) -> None\n\n\
365Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000366fd -- either an integer, or an object with a fileno() method returning an\n\
367 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000368events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369
370static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 PyObject *o, *key, *value;
374 int fd, events = POLLIN | POLLPRI | POLLOUT;
375 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
378 return NULL;
379 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 fd = PyObject_AsFileDescriptor(o);
382 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 /* Add entry to the internal dictionary: the key is the
385 file descriptor, and the value is the event mask. */
386 key = PyLong_FromLong(fd);
387 if (key == NULL)
388 return NULL;
389 value = PyLong_FromLong(events);
390 if (value == NULL) {
391 Py_DECREF(key);
392 return NULL;
393 }
394 err = PyDict_SetItem(self->dict, key, value);
395 Py_DECREF(key);
396 Py_DECREF(value);
397 if (err < 0)
398 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 self->ufd_uptodate = 0;
401
402 Py_INCREF(Py_None);
403 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404}
405
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000406PyDoc_STRVAR(poll_modify_doc,
407"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000408Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000409fd -- either an integer, or an object with a fileno() method returning an\n\
410 int.\n\
411events -- an optional bitmask describing the type of events to check for");
412
413static PyObject *
414poll_modify(pollObject *self, PyObject *args)
415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 PyObject *o, *key, *value;
417 int fd, events;
418 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
421 return NULL;
422 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 fd = PyObject_AsFileDescriptor(o);
425 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 /* Modify registered fd */
428 key = PyLong_FromLong(fd);
429 if (key == NULL)
430 return NULL;
431 if (PyDict_GetItem(self->dict, key) == NULL) {
432 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200433 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200434 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 return NULL;
436 }
437 value = PyLong_FromLong(events);
438 if (value == NULL) {
439 Py_DECREF(key);
440 return NULL;
441 }
442 err = PyDict_SetItem(self->dict, key, value);
443 Py_DECREF(key);
444 Py_DECREF(value);
445 if (err < 0)
446 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 self->ufd_uptodate = 0;
449
450 Py_INCREF(Py_None);
451 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000452}
453
454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000455PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000457Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
459static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 PyObject *key;
463 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 fd = PyObject_AsFileDescriptor( o );
466 if (fd == -1)
467 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 /* Check whether the fd is already in the array */
470 key = PyLong_FromLong(fd);
471 if (key == NULL)
472 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (PyDict_DelItem(self->dict, key) == -1) {
475 Py_DECREF(key);
476 /* This will simply raise the KeyError set by PyDict_DelItem
477 if the file descriptor isn't registered. */
478 return NULL;
479 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 Py_DECREF(key);
482 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 Py_INCREF(Py_None);
485 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486}
487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
490Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000491any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
493static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 PyObject *result_list = NULL, *tout = NULL;
497 int timeout = 0, poll_result, i, j;
498 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
501 return NULL;
502 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 /* Check values for timeout */
505 if (tout == NULL || tout == Py_None)
506 timeout = -1;
507 else if (!PyNumber_Check(tout)) {
508 PyErr_SetString(PyExc_TypeError,
509 "timeout must be an integer or None");
510 return NULL;
511 }
512 else {
513 tout = PyNumber_Long(tout);
514 if (!tout)
515 return NULL;
516 timeout = PyLong_AsLong(tout);
517 Py_DECREF(tout);
518 if (timeout == -1 && PyErr_Occurred())
519 return NULL;
520 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 /* Ensure the ufd array is up to date */
523 if (!self->ufd_uptodate)
524 if (update_ufd_array(self) == 0)
525 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 /* call poll() */
528 Py_BEGIN_ALLOW_THREADS
529 poll_result = poll(self->ufds, self->ufd_len, timeout);
530 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200533 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 return NULL;
535 }
536
537 /* build the result list */
538
539 result_list = PyList_New(poll_result);
540 if (!result_list)
541 return NULL;
542 else {
543 for (i = 0, j = 0; j < poll_result; j++) {
544 /* skip to the next fired descriptor */
545 while (!self->ufds[i].revents) {
546 i++;
547 }
548 /* if we hit a NULL return, set value to NULL
549 and break out of loop; code at end will
550 clean up result_list */
551 value = PyTuple_New(2);
552 if (value == NULL)
553 goto error;
554 num = PyLong_FromLong(self->ufds[i].fd);
555 if (num == NULL) {
556 Py_DECREF(value);
557 goto error;
558 }
559 PyTuple_SET_ITEM(value, 0, num);
560
561 /* The &0xffff is a workaround for AIX. 'revents'
562 is a 16-bit short, and IBM assigned POLLNVAL
563 to be 0x8000, so the conversion to int results
564 in a negative number. See SF bug #923315. */
565 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
566 if (num == NULL) {
567 Py_DECREF(value);
568 goto error;
569 }
570 PyTuple_SET_ITEM(value, 1, num);
571 if ((PyList_SetItem(result_list, j, value)) == -1) {
572 Py_DECREF(value);
573 goto error;
574 }
575 i++;
576 }
577 }
578 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000579
580 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 Py_DECREF(result_list);
582 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583}
584
585static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 {"register", (PyCFunction)poll_register,
587 METH_VARARGS, poll_register_doc},
588 {"modify", (PyCFunction)poll_modify,
589 METH_VARARGS, poll_modify_doc},
590 {"unregister", (PyCFunction)poll_unregister,
591 METH_O, poll_unregister_doc},
592 {"poll", (PyCFunction)poll_poll,
593 METH_VARARGS, poll_poll_doc},
594 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000595};
596
597static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000598newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 pollObject *self;
601 self = PyObject_New(pollObject, &poll_Type);
602 if (self == NULL)
603 return NULL;
604 /* ufd_uptodate is a Boolean, denoting whether the
605 array pointed to by ufds matches the contents of the dictionary. */
606 self->ufd_uptodate = 0;
607 self->ufds = NULL;
608 self->dict = PyDict_New();
609 if (self->dict == NULL) {
610 Py_DECREF(self);
611 return NULL;
612 }
613 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000614}
615
616static void
617poll_dealloc(pollObject *self)
618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 if (self->ufds != NULL)
620 PyMem_DEL(self->ufds);
621 Py_XDECREF(self->dict);
622 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623}
624
Tim Peters0c322792002-07-17 16:49:03 +0000625static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 /* The ob_type field must be initialized in the module init function
627 * to be portable to Windows without using C++. */
628 PyVarObject_HEAD_INIT(NULL, 0)
629 "select.poll", /*tp_name*/
630 sizeof(pollObject), /*tp_basicsize*/
631 0, /*tp_itemsize*/
632 /* methods */
633 (destructor)poll_dealloc, /*tp_dealloc*/
634 0, /*tp_print*/
635 0, /*tp_getattr*/
636 0, /*tp_setattr*/
637 0, /*tp_reserved*/
638 0, /*tp_repr*/
639 0, /*tp_as_number*/
640 0, /*tp_as_sequence*/
641 0, /*tp_as_mapping*/
642 0, /*tp_hash*/
643 0, /*tp_call*/
644 0, /*tp_str*/
645 0, /*tp_getattro*/
646 0, /*tp_setattro*/
647 0, /*tp_as_buffer*/
648 Py_TPFLAGS_DEFAULT, /*tp_flags*/
649 0, /*tp_doc*/
650 0, /*tp_traverse*/
651 0, /*tp_clear*/
652 0, /*tp_richcompare*/
653 0, /*tp_weaklistoffset*/
654 0, /*tp_iter*/
655 0, /*tp_iternext*/
656 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657};
658
Jesus Cead8b9ae62011-11-14 19:07:41 +0100659#ifdef HAVE_SYS_DEVPOLL_H
660typedef struct {
661 PyObject_HEAD
662 int fd_devpoll;
663 int max_n_fds;
664 int n_fds;
665 struct pollfd *fds;
666} devpollObject;
667
668static PyTypeObject devpoll_Type;
669
670static int devpoll_flush(devpollObject *self)
671{
672 int size, n;
673
674 if (!self->n_fds) return 0;
675
676 size = sizeof(struct pollfd)*self->n_fds;
677 self->n_fds = 0;
678
679 Py_BEGIN_ALLOW_THREADS
680 n = write(self->fd_devpoll, self->fds, size);
681 Py_END_ALLOW_THREADS
682
683 if (n == -1 ) {
684 PyErr_SetFromErrno(PyExc_IOError);
685 return -1;
686 }
687 if (n < size) {
688 /*
689 ** Data writed to /dev/poll is a binary data structure. It is not
690 ** clear what to do if a partial write occurred. For now, raise
691 ** an exception and see if we actually found this problem in
692 ** the wild.
693 ** See http://bugs.python.org/issue6397.
694 */
695 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
696 "Please, report at http://bugs.python.org/. "
697 "Data to report: Size tried: %d, actual size written: %d.",
698 size, n);
699 return -1;
700 }
701 return 0;
702}
703
704static PyObject *
705internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
706{
707 PyObject *o;
708 int fd, events = POLLIN | POLLPRI | POLLOUT;
709
710 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
711 return NULL;
712 }
713
714 fd = PyObject_AsFileDescriptor(o);
715 if (fd == -1) return NULL;
716
717 if (remove) {
718 self->fds[self->n_fds].fd = fd;
719 self->fds[self->n_fds].events = POLLREMOVE;
720
721 if (++self->n_fds == self->max_n_fds) {
722 if (devpoll_flush(self))
723 return NULL;
724 }
725 }
726
727 self->fds[self->n_fds].fd = fd;
728 self->fds[self->n_fds].events = events;
729
730 if (++self->n_fds == self->max_n_fds) {
731 if (devpoll_flush(self))
732 return NULL;
733 }
734
735 Py_RETURN_NONE;
736}
737
738PyDoc_STRVAR(devpoll_register_doc,
739"register(fd [, eventmask] ) -> None\n\n\
740Register a file descriptor with the polling object.\n\
741fd -- either an integer, or an object with a fileno() method returning an\n\
742 int.\n\
743events -- an optional bitmask describing the type of events to check for");
744
745static PyObject *
746devpoll_register(devpollObject *self, PyObject *args)
747{
748 return internal_devpoll_register(self, args, 0);
749}
750
751PyDoc_STRVAR(devpoll_modify_doc,
752"modify(fd[, eventmask]) -> None\n\n\
753Modify a possible already registered file descriptor.\n\
754fd -- either an integer, or an object with a fileno() method returning an\n\
755 int.\n\
756events -- an optional bitmask describing the type of events to check for");
757
758static PyObject *
759devpoll_modify(devpollObject *self, PyObject *args)
760{
761 return internal_devpoll_register(self, args, 1);
762}
763
764
765PyDoc_STRVAR(devpoll_unregister_doc,
766"unregister(fd) -> None\n\n\
767Remove a file descriptor being tracked by the polling object.");
768
769static PyObject *
770devpoll_unregister(devpollObject *self, PyObject *o)
771{
772 int fd;
773
774 fd = PyObject_AsFileDescriptor( o );
775 if (fd == -1)
776 return NULL;
777
778 self->fds[self->n_fds].fd = fd;
779 self->fds[self->n_fds].events = POLLREMOVE;
780
781 if (++self->n_fds == self->max_n_fds) {
782 if (devpoll_flush(self))
783 return NULL;
784 }
785
786 Py_RETURN_NONE;
787}
788
789PyDoc_STRVAR(devpoll_poll_doc,
790"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
791Polls the set of registered file descriptors, returning a list containing \n\
792any descriptors that have events or errors to report.");
793
794static PyObject *
795devpoll_poll(devpollObject *self, PyObject *args)
796{
797 struct dvpoll dvp;
798 PyObject *result_list = NULL, *tout = NULL;
799 int poll_result, i;
800 long timeout;
801 PyObject *value, *num1, *num2;
802
803 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
804 return NULL;
805 }
806
807 /* Check values for timeout */
808 if (tout == NULL || tout == Py_None)
809 timeout = -1;
810 else if (!PyNumber_Check(tout)) {
811 PyErr_SetString(PyExc_TypeError,
812 "timeout must be an integer or None");
813 return NULL;
814 }
815 else {
816 tout = PyNumber_Long(tout);
817 if (!tout)
818 return NULL;
819 timeout = PyLong_AsLong(tout);
820 Py_DECREF(tout);
821 if (timeout == -1 && PyErr_Occurred())
822 return NULL;
823 }
824
825 if ((timeout < -1) || (timeout > INT_MAX)) {
826 PyErr_SetString(PyExc_OverflowError,
827 "timeout is out of range");
828 return NULL;
829 }
830
831 if (devpoll_flush(self))
832 return NULL;
833
834 dvp.dp_fds = self->fds;
835 dvp.dp_nfds = self->max_n_fds;
836 dvp.dp_timeout = timeout;
837
838 /* call devpoll() */
839 Py_BEGIN_ALLOW_THREADS
840 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
841 Py_END_ALLOW_THREADS
842
843 if (poll_result < 0) {
844 PyErr_SetFromErrno(PyExc_IOError);
845 return NULL;
846 }
847
848 /* build the result list */
849
850 result_list = PyList_New(poll_result);
851 if (!result_list)
852 return NULL;
853 else {
854 for (i = 0; i < poll_result; i++) {
855 num1 = PyLong_FromLong(self->fds[i].fd);
856 num2 = PyLong_FromLong(self->fds[i].revents);
857 if ((num1 == NULL) || (num2 == NULL)) {
858 Py_XDECREF(num1);
859 Py_XDECREF(num2);
860 goto error;
861 }
862 value = PyTuple_Pack(2, num1, num2);
863 Py_DECREF(num1);
864 Py_DECREF(num2);
865 if (value == NULL)
866 goto error;
867 if ((PyList_SetItem(result_list, i, value)) == -1) {
868 Py_DECREF(value);
869 goto error;
870 }
871 }
872 }
873
874 return result_list;
875
876 error:
877 Py_DECREF(result_list);
878 return NULL;
879}
880
881static PyMethodDef devpoll_methods[] = {
882 {"register", (PyCFunction)devpoll_register,
883 METH_VARARGS, devpoll_register_doc},
884 {"modify", (PyCFunction)devpoll_modify,
885 METH_VARARGS, devpoll_modify_doc},
886 {"unregister", (PyCFunction)devpoll_unregister,
887 METH_O, devpoll_unregister_doc},
888 {"poll", (PyCFunction)devpoll_poll,
889 METH_VARARGS, devpoll_poll_doc},
890 {NULL, NULL} /* sentinel */
891};
892
893static devpollObject *
894newDevPollObject(void)
895{
896 devpollObject *self;
897 int fd_devpoll, limit_result;
898 struct pollfd *fds;
899 struct rlimit limit;
900
901 Py_BEGIN_ALLOW_THREADS
902 /*
903 ** If we try to process more that getrlimit()
904 ** fds, the kernel will give an error, so
905 ** we set the limit here. It is a dynamic
906 ** value, because we can change rlimit() anytime.
907 */
908 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
909 if (limit_result != -1)
910 fd_devpoll = open("/dev/poll", O_RDWR);
911 Py_END_ALLOW_THREADS
912
913 if (limit_result == -1) {
914 PyErr_SetFromErrno(PyExc_OSError);
915 return NULL;
916 }
917 if (fd_devpoll == -1) {
918 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
919 return NULL;
920 }
921
922 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
923 if (fds == NULL) {
924 close(fd_devpoll);
925 PyErr_NoMemory();
926 return NULL;
927 }
928
929 self = PyObject_New(devpollObject, &devpoll_Type);
930 if (self == NULL) {
931 close(fd_devpoll);
932 PyMem_DEL(fds);
933 return NULL;
934 }
935 self->fd_devpoll = fd_devpoll;
936 self->max_n_fds = limit.rlim_cur;
937 self->n_fds = 0;
938 self->fds = fds;
939
940 return self;
941}
942
943static void
944devpoll_dealloc(devpollObject *self)
945{
946 Py_BEGIN_ALLOW_THREADS
947 close(self->fd_devpoll);
948 Py_END_ALLOW_THREADS
949
950 PyMem_DEL(self->fds);
951
952 PyObject_Del(self);
953}
954
955static PyTypeObject devpoll_Type = {
956 /* The ob_type field must be initialized in the module init function
957 * to be portable to Windows without using C++. */
958 PyVarObject_HEAD_INIT(NULL, 0)
959 "select.devpoll", /*tp_name*/
960 sizeof(devpollObject), /*tp_basicsize*/
961 0, /*tp_itemsize*/
962 /* methods */
963 (destructor)devpoll_dealloc, /*tp_dealloc*/
964 0, /*tp_print*/
965 0, /*tp_getattr*/
966 0, /*tp_setattr*/
967 0, /*tp_reserved*/
968 0, /*tp_repr*/
969 0, /*tp_as_number*/
970 0, /*tp_as_sequence*/
971 0, /*tp_as_mapping*/
972 0, /*tp_hash*/
973 0, /*tp_call*/
974 0, /*tp_str*/
975 0, /*tp_getattro*/
976 0, /*tp_setattro*/
977 0, /*tp_as_buffer*/
978 Py_TPFLAGS_DEFAULT, /*tp_flags*/
979 0, /*tp_doc*/
980 0, /*tp_traverse*/
981 0, /*tp_clear*/
982 0, /*tp_richcompare*/
983 0, /*tp_weaklistoffset*/
984 0, /*tp_iter*/
985 0, /*tp_iternext*/
986 devpoll_methods, /*tp_methods*/
987};
988#endif /* HAVE_SYS_DEVPOLL_H */
989
990
991
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000992PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000993"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000994unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000995
996static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000997select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001000}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001
Jesus Cead8b9ae62011-11-14 19:07:41 +01001002#ifdef HAVE_SYS_DEVPOLL_H
1003PyDoc_STRVAR(devpoll_doc,
1004"Returns a polling object, which supports registering and\n\
1005unregistering file descriptors, and then polling them for I/O events.");
1006
1007static PyObject *
1008select_devpoll(PyObject *self, PyObject *unused)
1009{
1010 return (PyObject *)newDevPollObject();
1011}
1012#endif
1013
1014
Thomas Wouters477c8d52006-05-27 19:21:47 +00001015#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001017 * On some systems poll() sets errno on invalid file descriptors. We test
1018 * for this at runtime because this bug may be fixed or introduced between
1019 * OS releases.
1020 */
1021static int select_have_broken_poll(void)
1022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 int poll_test;
1024 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 /* Create a file descriptor to make invalid */
1029 if (pipe(filedes) < 0) {
1030 return 1;
1031 }
1032 poll_struct.fd = filedes[0];
1033 close(filedes[0]);
1034 close(filedes[1]);
1035 poll_test = poll(&poll_struct, 1, 0);
1036 if (poll_test < 0) {
1037 return 1;
1038 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1039 return 1;
1040 }
1041 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042}
1043#endif /* __APPLE__ */
1044
1045#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001046
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001047#ifdef HAVE_EPOLL
1048/* **************************************************************************
1049 * epoll interface for Linux 2.6
1050 *
1051 * Written by Christian Heimes
1052 * Inspired by Twisted's _epoll.pyx and select.poll()
1053 */
1054
1055#ifdef HAVE_SYS_EPOLL_H
1056#include <sys/epoll.h>
1057#endif
1058
1059typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyObject_HEAD
1061 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001062} pyEpoll_Object;
1063
1064static PyTypeObject pyEpoll_Type;
1065#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1066
1067static PyObject *
1068pyepoll_err_closed(void)
1069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1071 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001072}
1073
1074static int
1075pyepoll_internal_close(pyEpoll_Object *self)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 int save_errno = 0;
1078 if (self->epfd >= 0) {
1079 int epfd = self->epfd;
1080 self->epfd = -1;
1081 Py_BEGIN_ALLOW_THREADS
1082 if (close(epfd) < 0)
1083 save_errno = errno;
1084 Py_END_ALLOW_THREADS
1085 }
1086 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001087}
1088
1089static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001090newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001091{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 assert(type != NULL && type->tp_alloc != NULL);
1095 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1096 if (self == NULL)
1097 return NULL;
1098
1099 if (fd == -1) {
1100 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001101#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001102 if (flags)
1103 self->epfd = epoll_create1(flags);
1104 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001105#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001106 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 Py_END_ALLOW_THREADS
1108 }
1109 else {
1110 self->epfd = fd;
1111 }
1112 if (self->epfd < 0) {
1113 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001114 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 return NULL;
1116 }
1117 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001118}
1119
1120
1121static PyObject *
1122pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1123{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001124 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001125 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001126
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001127 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1128 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001130 if (sizehint < 0) {
1131 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1132 return NULL;
1133 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001134
Benjamin Peterson95c16622011-12-27 15:36:32 -06001135 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001136}
1137
1138
1139static void
1140pyepoll_dealloc(pyEpoll_Object *self)
1141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 (void)pyepoll_internal_close(self);
1143 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001144}
1145
1146static PyObject*
1147pyepoll_close(pyEpoll_Object *self)
1148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 errno = pyepoll_internal_close(self);
1150 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001151 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 return NULL;
1153 }
1154 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001155}
1156
1157PyDoc_STRVAR(pyepoll_close_doc,
1158"close() -> None\n\
1159\n\
1160Close the epoll control file descriptor. Further operations on the epoll\n\
1161object will raise an exception.");
1162
1163static PyObject*
1164pyepoll_get_closed(pyEpoll_Object *self)
1165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 if (self->epfd < 0)
1167 Py_RETURN_TRUE;
1168 else
1169 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001170}
1171
1172static PyObject*
1173pyepoll_fileno(pyEpoll_Object *self)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 if (self->epfd < 0)
1176 return pyepoll_err_closed();
1177 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001178}
1179
1180PyDoc_STRVAR(pyepoll_fileno_doc,
1181"fileno() -> int\n\
1182\n\
1183Return the epoll control file descriptor.");
1184
1185static PyObject*
1186pyepoll_fromfd(PyObject *cls, PyObject *args)
1187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1191 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001192
Benjamin Peterson95c16622011-12-27 15:36:32 -06001193 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001194}
1195
1196PyDoc_STRVAR(pyepoll_fromfd_doc,
1197"fromfd(fd) -> epoll\n\
1198\n\
1199Create an epoll object from a given control fd.");
1200
1201static PyObject *
1202pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1203{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 struct epoll_event ev;
1205 int result;
1206 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 if (epfd < 0)
1209 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 fd = PyObject_AsFileDescriptor(pfd);
1212 if (fd == -1) {
1213 return NULL;
1214 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 switch(op) {
1217 case EPOLL_CTL_ADD:
1218 case EPOLL_CTL_MOD:
1219 ev.events = events;
1220 ev.data.fd = fd;
1221 Py_BEGIN_ALLOW_THREADS
1222 result = epoll_ctl(epfd, op, fd, &ev);
1223 Py_END_ALLOW_THREADS
1224 break;
1225 case EPOLL_CTL_DEL:
1226 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1227 * operation required a non-NULL pointer in event, even
1228 * though this argument is ignored. */
1229 Py_BEGIN_ALLOW_THREADS
1230 result = epoll_ctl(epfd, op, fd, &ev);
1231 if (errno == EBADF) {
1232 /* fd already closed */
1233 result = 0;
1234 errno = 0;
1235 }
1236 Py_END_ALLOW_THREADS
1237 break;
1238 default:
1239 result = -1;
1240 errno = EINVAL;
1241 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001244 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 return NULL;
1246 }
1247 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248}
1249
1250static PyObject *
1251pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 PyObject *pfd;
1254 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1255 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1258 &pfd, &events)) {
1259 return NULL;
1260 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001263}
1264
1265PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001266"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001267\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001268Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001269fd is the target file descriptor of the operation.\n\
1270events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001271is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1272\n\
1273The epoll interface supports all file descriptors that support poll.");
1274
1275static PyObject *
1276pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 PyObject *pfd;
1279 unsigned int events;
1280 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1283 &pfd, &events)) {
1284 return NULL;
1285 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001288}
1289
1290PyDoc_STRVAR(pyepoll_modify_doc,
1291"modify(fd, eventmask) -> None\n\
1292\n\
1293fd is the target file descriptor of the operation\n\
1294events is a bit set composed of the various EPOLL constants");
1295
1296static PyObject *
1297pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 PyObject *pfd;
1300 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1303 &pfd)) {
1304 return NULL;
1305 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001308}
1309
1310PyDoc_STRVAR(pyepoll_unregister_doc,
1311"unregister(fd) -> None\n\
1312\n\
1313fd is the target file descriptor of the operation.");
1314
1315static PyObject *
1316pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 double dtimeout = -1.;
1319 int timeout;
1320 int maxevents = -1;
1321 int nfds, i;
1322 PyObject *elist = NULL, *etuple = NULL;
1323 struct epoll_event *evs = NULL;
1324 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 if (self->epfd < 0)
1327 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1330 &dtimeout, &maxevents)) {
1331 return NULL;
1332 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 if (dtimeout < 0) {
1335 timeout = -1;
1336 }
1337 else if (dtimeout * 1000.0 > INT_MAX) {
1338 PyErr_SetString(PyExc_OverflowError,
1339 "timeout is too large");
1340 return NULL;
1341 }
1342 else {
1343 timeout = (int)(dtimeout * 1000.0);
1344 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 if (maxevents == -1) {
1347 maxevents = FD_SETSIZE-1;
1348 }
1349 else if (maxevents < 1) {
1350 PyErr_Format(PyExc_ValueError,
1351 "maxevents must be greater than 0, got %d",
1352 maxevents);
1353 return NULL;
1354 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 evs = PyMem_New(struct epoll_event, maxevents);
1357 if (evs == NULL) {
1358 Py_DECREF(self);
1359 PyErr_NoMemory();
1360 return NULL;
1361 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 Py_BEGIN_ALLOW_THREADS
1364 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1365 Py_END_ALLOW_THREADS
1366 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001367 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 goto error;
1369 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 elist = PyList_New(nfds);
1372 if (elist == NULL) {
1373 goto error;
1374 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 for (i = 0; i < nfds; i++) {
1377 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1378 if (etuple == NULL) {
1379 Py_CLEAR(elist);
1380 goto error;
1381 }
1382 PyList_SET_ITEM(elist, i, etuple);
1383 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384
Christian Heimesf6cd9672008-03-26 13:45:42 +00001385 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 PyMem_Free(evs);
1387 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388}
1389
1390PyDoc_STRVAR(pyepoll_poll_doc,
1391"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1392\n\
1393Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1394in seconds (as float). -1 makes poll wait indefinitely.\n\
1395Up to maxevents are returned to the caller.");
1396
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001397static PyObject *
1398pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1399{
1400 if (self->epfd < 0)
1401 return pyepoll_err_closed();
1402
1403 Py_INCREF(self);
1404 return (PyObject *)self;
1405}
1406
1407static PyObject *
1408pyepoll_exit(PyObject *self, PyObject *args)
1409{
1410 _Py_IDENTIFIER(close);
1411
1412 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1413}
1414
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001415static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 {"fromfd", (PyCFunction)pyepoll_fromfd,
1417 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1418 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1419 pyepoll_close_doc},
1420 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1421 pyepoll_fileno_doc},
1422 {"modify", (PyCFunction)pyepoll_modify,
1423 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1424 {"register", (PyCFunction)pyepoll_register,
1425 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1426 {"unregister", (PyCFunction)pyepoll_unregister,
1427 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1428 {"poll", (PyCFunction)pyepoll_poll,
1429 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001430 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1431 NULL},
1432 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1433 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001435};
1436
1437static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 {"closed", (getter)pyepoll_get_closed, NULL,
1439 "True if the epoll handler is closed"},
1440 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441};
1442
1443PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001444"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001445\n\
1446Returns an epolling object\n\
1447\n\
1448sizehint must be a positive integer or -1 for the default size. The\n\
1449sizehint is used to optimize internal data structures. It doesn't limit\n\
1450the maximum number of monitored events.");
1451
1452static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 PyVarObject_HEAD_INIT(NULL, 0)
1454 "select.epoll", /* tp_name */
1455 sizeof(pyEpoll_Object), /* tp_basicsize */
1456 0, /* tp_itemsize */
1457 (destructor)pyepoll_dealloc, /* tp_dealloc */
1458 0, /* tp_print */
1459 0, /* tp_getattr */
1460 0, /* tp_setattr */
1461 0, /* tp_reserved */
1462 0, /* tp_repr */
1463 0, /* tp_as_number */
1464 0, /* tp_as_sequence */
1465 0, /* tp_as_mapping */
1466 0, /* tp_hash */
1467 0, /* tp_call */
1468 0, /* tp_str */
1469 PyObject_GenericGetAttr, /* tp_getattro */
1470 0, /* tp_setattro */
1471 0, /* tp_as_buffer */
1472 Py_TPFLAGS_DEFAULT, /* tp_flags */
1473 pyepoll_doc, /* tp_doc */
1474 0, /* tp_traverse */
1475 0, /* tp_clear */
1476 0, /* tp_richcompare */
1477 0, /* tp_weaklistoffset */
1478 0, /* tp_iter */
1479 0, /* tp_iternext */
1480 pyepoll_methods, /* tp_methods */
1481 0, /* tp_members */
1482 pyepoll_getsetlist, /* tp_getset */
1483 0, /* tp_base */
1484 0, /* tp_dict */
1485 0, /* tp_descr_get */
1486 0, /* tp_descr_set */
1487 0, /* tp_dictoffset */
1488 0, /* tp_init */
1489 0, /* tp_alloc */
1490 pyepoll_new, /* tp_new */
1491 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001492};
1493
1494#endif /* HAVE_EPOLL */
1495
1496#ifdef HAVE_KQUEUE
1497/* **************************************************************************
1498 * kqueue interface for BSD
1499 *
1500 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1501 * All rights reserved.
1502 *
1503 * Redistribution and use in source and binary forms, with or without
1504 * modification, are permitted provided that the following conditions
1505 * are met:
1506 * 1. Redistributions of source code must retain the above copyright
1507 * notice, this list of conditions and the following disclaimer.
1508 * 2. Redistributions in binary form must reproduce the above copyright
1509 * notice, this list of conditions and the following disclaimer in the
1510 * documentation and/or other materials provided with the distribution.
1511 *
1512 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1513 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1514 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1515 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1516 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1517 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1518 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1519 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1520 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1521 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1522 * SUCH DAMAGE.
1523 */
1524
1525#ifdef HAVE_SYS_EVENT_H
1526#include <sys/event.h>
1527#endif
1528
1529PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001530"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001531\n\
1532This object is the equivalent of the struct kevent for the C API.\n\
1533\n\
1534See the kqueue manpage for more detailed information about the meaning\n\
1535of the arguments.\n\
1536\n\
1537One minor note: while you might hope that udata could store a\n\
1538reference to a python object, it cannot, because it is impossible to\n\
1539keep a proper reference count of the object once it's passed into the\n\
1540kernel. Therefore, I have restricted it to only storing an integer. I\n\
1541recommend ignoring it and simply using the 'ident' field to key off\n\
1542of. You could also set up a dictionary on the python side to store a\n\
1543udata->object mapping.");
1544
1545typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 PyObject_HEAD
1547 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001548} kqueue_event_Object;
1549
1550static PyTypeObject kqueue_event_Type;
1551
1552#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1553
1554typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 PyObject_HEAD
1556 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001557} kqueue_queue_Object;
1558
1559static PyTypeObject kqueue_queue_Type;
1560
1561#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1562
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001563#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1564# error uintptr_t does not match void *!
1565#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1566# define T_UINTPTRT T_ULONGLONG
1567# define T_INTPTRT T_LONGLONG
1568# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1569# define UINTPTRT_FMT_UNIT "K"
1570# define INTPTRT_FMT_UNIT "L"
1571#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1572# define T_UINTPTRT T_ULONG
1573# define T_INTPTRT T_LONG
1574# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1575# define UINTPTRT_FMT_UNIT "k"
1576# define INTPTRT_FMT_UNIT "l"
1577#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1578# define T_UINTPTRT T_UINT
1579# define T_INTPTRT T_INT
1580# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1581# define UINTPTRT_FMT_UNIT "I"
1582# define INTPTRT_FMT_UNIT "i"
1583#else
1584# error uintptr_t does not match int, long, or long long!
1585#endif
1586
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587/* Unfortunately, we can't store python objects in udata, because
1588 * kevents in the kernel can be removed without warning, which would
1589 * forever lose the refcount on the object stored with it.
1590 */
1591
1592#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1593static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1595 {"filter", T_SHORT, KQ_OFF(e.filter)},
1596 {"flags", T_USHORT, KQ_OFF(e.flags)},
1597 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1598 {"data", T_INTPTRT, KQ_OFF(e.data)},
1599 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1600 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601};
1602#undef KQ_OFF
1603
1604static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001605
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606kqueue_event_repr(kqueue_event_Object *s)
1607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 char buf[1024];
1609 PyOS_snprintf(
1610 buf, sizeof(buf),
1611 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1612 "data=0x%zd udata=%p>",
1613 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1614 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1615 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001616}
1617
1618static int
1619kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *pfd;
1622 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1623 "data", "udata", NULL};
1624 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1629 &pfd, &(self->e.filter), &(self->e.flags),
1630 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1631 return -1;
1632 }
1633
1634 if (PyLong_Check(pfd)) {
1635 self->e.ident = PyLong_AsUintptr_t(pfd);
1636 }
1637 else {
1638 self->e.ident = PyObject_AsFileDescriptor(pfd);
1639 }
1640 if (PyErr_Occurred()) {
1641 return -1;
1642 }
1643 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001644}
1645
1646static PyObject *
1647kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 if (!kqueue_event_Check(o)) {
1653 if (op == Py_EQ || op == Py_NE) {
1654 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1655 Py_INCREF(res);
1656 return res;
1657 }
1658 PyErr_Format(PyExc_TypeError,
1659 "can't compare %.200s to %.200s",
1660 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1661 return NULL;
1662 }
1663 if (((result = s->e.ident - o->e.ident) == 0) &&
1664 ((result = s->e.filter - o->e.filter) == 0) &&
1665 ((result = s->e.flags - o->e.flags) == 0) &&
1666 ((result = s->e.fflags - o->e.fflags) == 0) &&
1667 ((result = s->e.data - o->e.data) == 0) &&
1668 ((result = s->e.udata - o->e.udata) == 0)
1669 ) {
1670 result = 0;
1671 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 switch (op) {
1674 case Py_EQ:
1675 result = (result == 0);
1676 break;
1677 case Py_NE:
1678 result = (result != 0);
1679 break;
1680 case Py_LE:
1681 result = (result <= 0);
1682 break;
1683 case Py_GE:
1684 result = (result >= 0);
1685 break;
1686 case Py_LT:
1687 result = (result < 0);
1688 break;
1689 case Py_GT:
1690 result = (result > 0);
1691 break;
1692 }
1693 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001694}
1695
1696static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 PyVarObject_HEAD_INIT(NULL, 0)
1698 "select.kevent", /* tp_name */
1699 sizeof(kqueue_event_Object), /* tp_basicsize */
1700 0, /* tp_itemsize */
1701 0, /* tp_dealloc */
1702 0, /* tp_print */
1703 0, /* tp_getattr */
1704 0, /* tp_setattr */
1705 0, /* tp_reserved */
1706 (reprfunc)kqueue_event_repr, /* tp_repr */
1707 0, /* tp_as_number */
1708 0, /* tp_as_sequence */
1709 0, /* tp_as_mapping */
1710 0, /* tp_hash */
1711 0, /* tp_call */
1712 0, /* tp_str */
1713 0, /* tp_getattro */
1714 0, /* tp_setattro */
1715 0, /* tp_as_buffer */
1716 Py_TPFLAGS_DEFAULT, /* tp_flags */
1717 kqueue_event_doc, /* tp_doc */
1718 0, /* tp_traverse */
1719 0, /* tp_clear */
1720 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1721 0, /* tp_weaklistoffset */
1722 0, /* tp_iter */
1723 0, /* tp_iternext */
1724 0, /* tp_methods */
1725 kqueue_event_members, /* tp_members */
1726 0, /* tp_getset */
1727 0, /* tp_base */
1728 0, /* tp_dict */
1729 0, /* tp_descr_get */
1730 0, /* tp_descr_set */
1731 0, /* tp_dictoffset */
1732 (initproc)kqueue_event_init, /* tp_init */
1733 0, /* tp_alloc */
1734 0, /* tp_new */
1735 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001736};
1737
1738static PyObject *
1739kqueue_queue_err_closed(void)
1740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1742 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001743}
1744
1745static int
1746kqueue_queue_internal_close(kqueue_queue_Object *self)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 int save_errno = 0;
1749 if (self->kqfd >= 0) {
1750 int kqfd = self->kqfd;
1751 self->kqfd = -1;
1752 Py_BEGIN_ALLOW_THREADS
1753 if (close(kqfd) < 0)
1754 save_errno = errno;
1755 Py_END_ALLOW_THREADS
1756 }
1757 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001758}
1759
1760static PyObject *
1761newKqueue_Object(PyTypeObject *type, SOCKET fd)
1762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 kqueue_queue_Object *self;
1764 assert(type != NULL && type->tp_alloc != NULL);
1765 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1766 if (self == NULL) {
1767 return NULL;
1768 }
1769
1770 if (fd == -1) {
1771 Py_BEGIN_ALLOW_THREADS
1772 self->kqfd = kqueue();
1773 Py_END_ALLOW_THREADS
1774 }
1775 else {
1776 self->kqfd = fd;
1777 }
1778 if (self->kqfd < 0) {
1779 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001780 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 return NULL;
1782 }
1783 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001784}
1785
1786static PyObject *
1787kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1788{
1789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 if ((args != NULL && PyObject_Size(args)) ||
1791 (kwds != NULL && PyObject_Size(kwds))) {
1792 PyErr_SetString(PyExc_ValueError,
1793 "select.kqueue doesn't accept arguments");
1794 return NULL;
1795 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001798}
1799
1800static void
1801kqueue_queue_dealloc(kqueue_queue_Object *self)
1802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 kqueue_queue_internal_close(self);
1804 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001805}
1806
1807static PyObject*
1808kqueue_queue_close(kqueue_queue_Object *self)
1809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 errno = kqueue_queue_internal_close(self);
1811 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001812 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 return NULL;
1814 }
1815 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001816}
1817
1818PyDoc_STRVAR(kqueue_queue_close_doc,
1819"close() -> None\n\
1820\n\
1821Close the kqueue control file descriptor. Further operations on the kqueue\n\
1822object will raise an exception.");
1823
1824static PyObject*
1825kqueue_queue_get_closed(kqueue_queue_Object *self)
1826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 if (self->kqfd < 0)
1828 Py_RETURN_TRUE;
1829 else
1830 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831}
1832
1833static PyObject*
1834kqueue_queue_fileno(kqueue_queue_Object *self)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 if (self->kqfd < 0)
1837 return kqueue_queue_err_closed();
1838 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001839}
1840
1841PyDoc_STRVAR(kqueue_queue_fileno_doc,
1842"fileno() -> int\n\
1843\n\
1844Return the kqueue control file descriptor.");
1845
1846static PyObject*
1847kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1852 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001855}
1856
1857PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1858"fromfd(fd) -> kqueue\n\
1859\n\
1860Create a kqueue object from a given control fd.");
1861
1862static PyObject *
1863kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1864{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 int nevents = 0;
1866 int gotevents = 0;
1867 int nchanges = 0;
1868 int i = 0;
1869 PyObject *otimeout = NULL;
1870 PyObject *ch = NULL;
1871 PyObject *it = NULL, *ei = NULL;
1872 PyObject *result = NULL;
1873 struct kevent *evl = NULL;
1874 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001875 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 if (self->kqfd < 0)
1879 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1882 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 if (nevents < 0) {
1885 PyErr_Format(PyExc_ValueError,
1886 "Length of eventlist must be 0 or positive, got %d",
1887 nevents);
1888 return NULL;
1889 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 if (otimeout == Py_None || otimeout == NULL) {
1892 ptimeoutspec = NULL;
1893 }
1894 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001895 if (_PyTime_ObjectToTimespec(otimeout,
1896 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1897 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Victor Stinner5d272cc2012-03-13 13:35:55 +01001899 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 PyErr_SetString(PyExc_ValueError,
1901 "timeout must be positive or None");
1902 return NULL;
1903 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001904 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 }
1906 else {
1907 PyErr_Format(PyExc_TypeError,
1908 "timeout argument must be an number "
1909 "or None, got %.200s",
1910 Py_TYPE(otimeout)->tp_name);
1911 return NULL;
1912 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 if (ch != NULL && ch != Py_None) {
1915 it = PyObject_GetIter(ch);
1916 if (it == NULL) {
1917 PyErr_SetString(PyExc_TypeError,
1918 "changelist is not iterable");
1919 return NULL;
1920 }
1921 nchanges = PyObject_Size(ch);
1922 if (nchanges < 0) {
1923 goto error;
1924 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 chl = PyMem_New(struct kevent, nchanges);
1927 if (chl == NULL) {
1928 PyErr_NoMemory();
1929 goto error;
1930 }
1931 i = 0;
1932 while ((ei = PyIter_Next(it)) != NULL) {
1933 if (!kqueue_event_Check(ei)) {
1934 Py_DECREF(ei);
1935 PyErr_SetString(PyExc_TypeError,
1936 "changelist must be an iterable of "
1937 "select.kevent objects");
1938 goto error;
1939 } else {
1940 chl[i++] = ((kqueue_event_Object *)ei)->e;
1941 }
1942 Py_DECREF(ei);
1943 }
1944 }
1945 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 /* event list */
1948 if (nevents) {
1949 evl = PyMem_New(struct kevent, nevents);
1950 if (evl == NULL) {
1951 PyErr_NoMemory();
1952 goto error;
1953 }
1954 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 Py_BEGIN_ALLOW_THREADS
1957 gotevents = kevent(self->kqfd, chl, nchanges,
1958 evl, nevents, ptimeoutspec);
1959 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 if (gotevents == -1) {
1962 PyErr_SetFromErrno(PyExc_OSError);
1963 goto error;
1964 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 result = PyList_New(gotevents);
1967 if (result == NULL) {
1968 goto error;
1969 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 for (i = 0; i < gotevents; i++) {
1972 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1975 if (ch == NULL) {
1976 goto error;
1977 }
1978 ch->e = evl[i];
1979 PyList_SET_ITEM(result, i, (PyObject *)ch);
1980 }
1981 PyMem_Free(chl);
1982 PyMem_Free(evl);
1983 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001984
1985 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 PyMem_Free(chl);
1987 PyMem_Free(evl);
1988 Py_XDECREF(result);
1989 Py_XDECREF(it);
1990 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001991}
1992
1993PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001994"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001995\n\
1996Calls the kernel kevent function.\n\
1997- changelist must be a list of kevent objects describing the changes\n\
1998 to be made to the kernel's watch list or None.\n\
1999- max_events lets you specify the maximum number of events that the\n\
2000 kernel will return.\n\
2001- timeout is the maximum time to wait in seconds, or else None,\n\
2002 to wait forever. timeout accepts floats for smaller timeouts, too.");
2003
2004
2005static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2007 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2008 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2009 kqueue_queue_close_doc},
2010 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2011 kqueue_queue_fileno_doc},
2012 {"control", (PyCFunction)kqueue_queue_control,
2013 METH_VARARGS , kqueue_queue_control_doc},
2014 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002015};
2016
2017static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 {"closed", (getter)kqueue_queue_get_closed, NULL,
2019 "True if the kqueue handler is closed"},
2020 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002021};
2022
2023PyDoc_STRVAR(kqueue_queue_doc,
2024"Kqueue syscall wrapper.\n\
2025\n\
2026For example, to start watching a socket for input:\n\
2027>>> kq = kqueue()\n\
2028>>> sock = socket()\n\
2029>>> sock.connect((host, port))\n\
2030>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2031\n\
2032To wait one second for it to become writeable:\n\
2033>>> kq.control(None, 1, 1000)\n\
2034\n\
2035To stop listening:\n\
2036>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2037
2038static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 PyVarObject_HEAD_INIT(NULL, 0)
2040 "select.kqueue", /* tp_name */
2041 sizeof(kqueue_queue_Object), /* tp_basicsize */
2042 0, /* tp_itemsize */
2043 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2044 0, /* tp_print */
2045 0, /* tp_getattr */
2046 0, /* tp_setattr */
2047 0, /* tp_reserved */
2048 0, /* tp_repr */
2049 0, /* tp_as_number */
2050 0, /* tp_as_sequence */
2051 0, /* tp_as_mapping */
2052 0, /* tp_hash */
2053 0, /* tp_call */
2054 0, /* tp_str */
2055 0, /* tp_getattro */
2056 0, /* tp_setattro */
2057 0, /* tp_as_buffer */
2058 Py_TPFLAGS_DEFAULT, /* tp_flags */
2059 kqueue_queue_doc, /* tp_doc */
2060 0, /* tp_traverse */
2061 0, /* tp_clear */
2062 0, /* tp_richcompare */
2063 0, /* tp_weaklistoffset */
2064 0, /* tp_iter */
2065 0, /* tp_iternext */
2066 kqueue_queue_methods, /* tp_methods */
2067 0, /* tp_members */
2068 kqueue_queue_getsetlist, /* tp_getset */
2069 0, /* tp_base */
2070 0, /* tp_dict */
2071 0, /* tp_descr_get */
2072 0, /* tp_descr_set */
2073 0, /* tp_dictoffset */
2074 0, /* tp_init */
2075 0, /* tp_alloc */
2076 kqueue_queue_new, /* tp_new */
2077 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002078};
2079
2080#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002081
2082
2083
2084
2085
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002086/* ************************************************************************ */
2087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002088PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002089"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2090\n\
2091Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002092The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002093rlist -- wait until ready for reading\n\
2094wlist -- wait until ready for writing\n\
2095xlist -- wait for an ``exceptional condition''\n\
2096If only one kind of condition is required, pass [] for the other lists.\n\
2097A file descriptor is either a socket or file object, or a small integer\n\
2098gotten from a fileno() method call on one of those.\n\
2099\n\
2100The optional 4th argument specifies a timeout in seconds; it may be\n\
2101a floating point number to specify fractions of seconds. If it is absent\n\
2102or None, the call will never time out.\n\
2103\n\
2104The return value is a tuple of three lists corresponding to the first three\n\
2105arguments; each contains the subset of the corresponding file descriptors\n\
2106that are ready.\n\
2107\n\
2108*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002109On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002110descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002111
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002112static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002114#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002116#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002117#ifdef HAVE_SYS_DEVPOLL_H
2118 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2119#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002121};
2122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002123PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002124"This module supports asynchronous I/O on multiple file descriptors.\n\
2125\n\
2126*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002127On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002128
Martin v. Löwis1a214512008-06-11 05:26:20 +00002129
2130static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 PyModuleDef_HEAD_INIT,
2132 "select",
2133 module_doc,
2134 -1,
2135 select_methods,
2136 NULL,
2137 NULL,
2138 NULL,
2139 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002140};
2141
Jesus Cead8b9ae62011-11-14 19:07:41 +01002142
2143
2144
Mark Hammond62b1ab12002-07-23 06:31:15 +00002145PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002146PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 PyObject *m;
2149 m = PyModule_Create(&selectmodule);
2150 if (m == NULL)
2151 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002152
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002153 Py_INCREF(PyExc_OSError);
2154 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002155
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002156#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002157#ifdef HAVE_BROKEN_PIPE_BUF
2158#undef PIPE_BUF
2159#define PIPE_BUF 512
2160#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002162#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002163
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002164#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002165#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 if (select_have_broken_poll()) {
2167 if (PyObject_DelAttrString(m, "poll") == -1) {
2168 PyErr_Clear();
2169 }
2170 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002171#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002173#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 if (PyType_Ready(&poll_Type) < 0)
2175 return NULL;
2176 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2177 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2178 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2179 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2180 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2181 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002182
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002183#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002185#endif
2186#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002188#endif
2189#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002191#endif
2192#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002194#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002195#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002197#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002199#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002200
Jesus Cead8b9ae62011-11-14 19:07:41 +01002201#ifdef HAVE_SYS_DEVPOLL_H
2202 if (PyType_Ready(&devpoll_Type) < 0)
2203 return NULL;
2204#endif
2205
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002206#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002207 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2208 if (PyType_Ready(&pyEpoll_Type) < 0)
2209 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 Py_INCREF(&pyEpoll_Type);
2212 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002214 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2215 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2216 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2217 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2218 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2219 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002220#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 /* Kernel 2.6.2+ */
2222 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002223#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2225 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2226 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2227 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2228 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2229 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002230
Benjamin Peterson95c16622011-12-27 15:36:32 -06002231#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002232 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002233#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002234#endif /* HAVE_EPOLL */
2235
2236#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 kqueue_event_Type.tp_new = PyType_GenericNew;
2238 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2239 if(PyType_Ready(&kqueue_event_Type) < 0)
2240 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 Py_INCREF(&kqueue_event_Type);
2243 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2246 if(PyType_Ready(&kqueue_queue_Type) < 0)
2247 return NULL;
2248 Py_INCREF(&kqueue_queue_Type);
2249 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2250
2251 /* event filters */
2252 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2253 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2254 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2255 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2256 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002257#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2261 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 /* event flags */
2264 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2265 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2266 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2267 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2268 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2269 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2272 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2275 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 /* READ WRITE filter flag */
2278 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 /* VNODE filter flags */
2281 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2282 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2283 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2284 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2285 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2286 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2287 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 /* PROC filter flags */
2290 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2291 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2292 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2293 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2294 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2297 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2298 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2299
2300 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002301#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2303 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2304 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002305#endif
2306
2307#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002309}