blob: 9e53773de3056b9aec80ac381fa42960a644019a [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;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010092 Py_ssize_t i;
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
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100103 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 SOCKET v;
105
106 /* any intervening fileno() calls could decr this refcnt */
107 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200108 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 Py_INCREF(o);
111 v = PyObject_AsFileDescriptor( o );
112 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000114#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000116#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200117 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 PyErr_SetString(PyExc_ValueError,
119 "filedescriptor out of range in select()");
120 goto finally;
121 }
122 if (v > max)
123 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000124#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 /* add object and its file descriptor to the list */
128 if (index >= FD_SETSIZE) {
129 PyErr_SetString(PyExc_ValueError,
130 "too many file descriptors in select()");
131 goto finally;
132 }
133 fd2obj[index].obj = o;
134 fd2obj[index].fd = v;
135 fd2obj[index].sentinel = 0;
136 fd2obj[++index].sentinel = -1;
137 }
138 Py_DECREF(fast_seq);
139 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000140
141 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 Py_XDECREF(o);
143 Py_DECREF(fast_seq);
144 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000145}
146
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000147/* returns NULL and sets the Python exception if an error occurred */
148static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000149set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 int i, j, count=0;
152 PyObject *list, *o;
153 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
156 if (FD_ISSET(fd2obj[j].fd, set))
157 count++;
158 }
159 list = PyList_New(count);
160 if (!list)
161 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 i = 0;
164 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
165 fd = fd2obj[j].fd;
166 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 o = fd2obj[j].obj;
168 fd2obj[j].obj = NULL;
169 /* transfer ownership */
170 if (PyList_SetItem(list, i, o) < 0)
171 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 i++;
174 }
175 }
176 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 Py_DECREF(list);
179 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000180}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000181
Barry Warsawb44740f2001-08-16 16:52:59 +0000182#undef SELECT_USES_HEAP
183#if FD_SETSIZE > 1024
184#define SELECT_USES_HEAP
185#endif /* FD_SETSIZE > 1024 */
186
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000187static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000188select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000189{
Barry Warsawb44740f2001-08-16 16:52:59 +0000190#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 /* XXX: All this should probably be implemented as follows:
194 * - find the highest descriptor we're interested in
195 * - add one
196 * - that's the size
197 * See: Stevens, APitUE, $12.5.1
198 */
199 pylist rfd2obj[FD_SETSIZE + 1];
200 pylist wfd2obj[FD_SETSIZE + 1];
201 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000202#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 PyObject *ifdlist, *ofdlist, *efdlist;
204 PyObject *ret = NULL;
205 PyObject *tout = Py_None;
206 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 int imax, omax, emax, max;
209 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 /* convert arguments */
212 if (!PyArg_UnpackTuple(args, "select", 3, 4,
213 &ifdlist, &ofdlist, &efdlist, &tout))
214 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 if (tout == Py_None)
217 tvp = (struct timeval *)0;
218 else if (!PyNumber_Check(tout)) {
219 PyErr_SetString(PyExc_TypeError,
220 "timeout must be a float or None");
221 return NULL;
222 }
223 else {
Victor Stinnerb2a37732012-03-14 00:20:51 +0100224#ifdef MS_WINDOWS
225 time_t sec;
226 if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 return NULL;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100228 assert(sizeof(tv.tv_sec) == sizeof(long));
229#if SIZEOF_TIME_T > SIZEOF_LONG
230 if (sec > LONG_MAX) {
231 PyErr_SetString(PyExc_OverflowError,
232 "timeout is too large");
233 return NULL;
234 }
235#endif
236 tv.tv_sec = (long)sec;
237#else
Brett Cannon8798ad32012-04-07 14:59:29 -0400238 /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4
239 bytes as required), but no longer defined by a long. */
Benjamin Peterson6f3e5e42012-09-11 12:05:05 -0400240 long tv_usec;
Brett Cannon8798ad32012-04-07 14:59:29 -0400241 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1)
Victor Stinnerb2a37732012-03-14 00:20:51 +0100242 return NULL;
Brett Cannon8798ad32012-04-07 14:59:29 -0400243 tv.tv_usec = tv_usec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100244#endif
Victor Stinner5d272cc2012-03-13 13:35:55 +0100245 if (tv.tv_sec < 0) {
246 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 return NULL;
248 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 tvp = &tv;
250 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000251
Guido van Rossumed233a51992-06-23 09:07:03 +0000252
Barry Warsawb44740f2001-08-16 16:52:59 +0000253#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 /* Allocate memory for the lists */
255 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
256 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
257 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
258 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
259 if (rfd2obj) PyMem_DEL(rfd2obj);
260 if (wfd2obj) PyMem_DEL(wfd2obj);
261 if (efd2obj) PyMem_DEL(efd2obj);
262 return PyErr_NoMemory();
263 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000264#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 /* Convert sequences to fd_sets, and get maximum fd number
266 * propagates the Python exception set in seq2set()
267 */
268 rfd2obj[0].sentinel = -1;
269 wfd2obj[0].sentinel = -1;
270 efd2obj[0].sentinel = -1;
271 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
272 goto finally;
273 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
274 goto finally;
275 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
276 goto finally;
277 max = imax;
278 if (omax > max) max = omax;
279 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 Py_BEGIN_ALLOW_THREADS
282 n = select(max, &ifdset, &ofdset, &efdset, tvp);
283 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000284
Thomas Heller106f4c72002-09-24 16:51:00 +0000285#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200287 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000289#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200291 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000293#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 else {
295 /* any of these three calls can raise an exception. it's more
296 convenient to test for this after all three calls... but
297 is that acceptable?
298 */
299 ifdlist = set2list(&ifdset, rfd2obj);
300 ofdlist = set2list(&ofdset, wfd2obj);
301 efdlist = set2list(&efdset, efd2obj);
302 if (PyErr_Occurred())
303 ret = NULL;
304 else
305 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 Py_DECREF(ifdlist);
308 Py_DECREF(ofdlist);
309 Py_DECREF(efdlist);
310 }
311
Barry Warsawc1cb3601996-12-12 22:16:21 +0000312 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 reap_obj(rfd2obj);
314 reap_obj(wfd2obj);
315 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000316#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 PyMem_DEL(rfd2obj);
318 PyMem_DEL(wfd2obj);
319 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000320#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000322}
323
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000324#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000326 * poll() support
327 */
328
329typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 PyObject_HEAD
331 PyObject *dict;
332 int ufd_uptodate;
333 int ufd_len;
334 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335} pollObject;
336
Jeremy Hylton938ace62002-07-17 16:30:39 +0000337static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340 contained within a pollObject. Return 1 on success, 0 on an error.
341*/
342
343static int
344update_ufd_array(pollObject *self)
345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 Py_ssize_t i, pos;
347 PyObject *key, *value;
348 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 self->ufd_len = PyDict_Size(self->dict);
351 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
352 if (self->ufds == NULL) {
353 self->ufds = old_ufds;
354 PyErr_NoMemory();
355 return 0;
356 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 i = pos = 0;
359 while (PyDict_Next(self->dict, &pos, &key, &value)) {
360 self->ufds[i].fd = PyLong_AsLong(key);
361 self->ufds[i].events = (short)PyLong_AsLong(value);
362 i++;
363 }
364 self->ufd_uptodate = 1;
365 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366}
367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000368PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369"register(fd [, eventmask] ) -> None\n\n\
370Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000371fd -- either an integer, or an object with a fileno() method returning an\n\
372 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000373events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374
375static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 PyObject *o, *key, *value;
379 int fd, events = POLLIN | POLLPRI | POLLOUT;
380 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
383 return NULL;
384 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 fd = PyObject_AsFileDescriptor(o);
387 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 /* Add entry to the internal dictionary: the key is the
390 file descriptor, and the value is the event mask. */
391 key = PyLong_FromLong(fd);
392 if (key == NULL)
393 return NULL;
394 value = PyLong_FromLong(events);
395 if (value == NULL) {
396 Py_DECREF(key);
397 return NULL;
398 }
399 err = PyDict_SetItem(self->dict, key, value);
400 Py_DECREF(key);
401 Py_DECREF(value);
402 if (err < 0)
403 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 self->ufd_uptodate = 0;
406
407 Py_INCREF(Py_None);
408 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409}
410
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000411PyDoc_STRVAR(poll_modify_doc,
412"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000413Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000414fd -- either an integer, or an object with a fileno() method returning an\n\
415 int.\n\
416events -- an optional bitmask describing the type of events to check for");
417
418static PyObject *
419poll_modify(pollObject *self, PyObject *args)
420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 PyObject *o, *key, *value;
422 int fd, events;
423 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
426 return NULL;
427 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 fd = PyObject_AsFileDescriptor(o);
430 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 /* Modify registered fd */
433 key = PyLong_FromLong(fd);
434 if (key == NULL)
435 return NULL;
436 if (PyDict_GetItem(self->dict, key) == NULL) {
437 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200438 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200439 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 return NULL;
441 }
442 value = PyLong_FromLong(events);
443 if (value == NULL) {
444 Py_DECREF(key);
445 return NULL;
446 }
447 err = PyDict_SetItem(self->dict, key, value);
448 Py_DECREF(key);
449 Py_DECREF(value);
450 if (err < 0)
451 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 self->ufd_uptodate = 0;
454
455 Py_INCREF(Py_None);
456 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000457}
458
459
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000460PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000462Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463
464static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 PyObject *key;
468 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 fd = PyObject_AsFileDescriptor( o );
471 if (fd == -1)
472 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 /* Check whether the fd is already in the array */
475 key = PyLong_FromLong(fd);
476 if (key == NULL)
477 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 if (PyDict_DelItem(self->dict, key) == -1) {
480 Py_DECREF(key);
481 /* This will simply raise the KeyError set by PyDict_DelItem
482 if the file descriptor isn't registered. */
483 return NULL;
484 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 Py_DECREF(key);
487 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 Py_INCREF(Py_None);
490 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491}
492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000493PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
495Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000496any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000497
498static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 PyObject *result_list = NULL, *tout = NULL;
502 int timeout = 0, poll_result, i, j;
503 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
506 return NULL;
507 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 /* Check values for timeout */
510 if (tout == NULL || tout == Py_None)
511 timeout = -1;
512 else if (!PyNumber_Check(tout)) {
513 PyErr_SetString(PyExc_TypeError,
514 "timeout must be an integer or None");
515 return NULL;
516 }
517 else {
518 tout = PyNumber_Long(tout);
519 if (!tout)
520 return NULL;
521 timeout = PyLong_AsLong(tout);
522 Py_DECREF(tout);
523 if (timeout == -1 && PyErr_Occurred())
524 return NULL;
525 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 /* Ensure the ufd array is up to date */
528 if (!self->ufd_uptodate)
529 if (update_ufd_array(self) == 0)
530 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 /* call poll() */
533 Py_BEGIN_ALLOW_THREADS
534 poll_result = poll(self->ufds, self->ufd_len, timeout);
535 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200538 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 return NULL;
540 }
541
542 /* build the result list */
543
544 result_list = PyList_New(poll_result);
545 if (!result_list)
546 return NULL;
547 else {
548 for (i = 0, j = 0; j < poll_result; j++) {
549 /* skip to the next fired descriptor */
550 while (!self->ufds[i].revents) {
551 i++;
552 }
553 /* if we hit a NULL return, set value to NULL
554 and break out of loop; code at end will
555 clean up result_list */
556 value = PyTuple_New(2);
557 if (value == NULL)
558 goto error;
559 num = PyLong_FromLong(self->ufds[i].fd);
560 if (num == NULL) {
561 Py_DECREF(value);
562 goto error;
563 }
564 PyTuple_SET_ITEM(value, 0, num);
565
566 /* The &0xffff is a workaround for AIX. 'revents'
567 is a 16-bit short, and IBM assigned POLLNVAL
568 to be 0x8000, so the conversion to int results
569 in a negative number. See SF bug #923315. */
570 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
571 if (num == NULL) {
572 Py_DECREF(value);
573 goto error;
574 }
575 PyTuple_SET_ITEM(value, 1, num);
576 if ((PyList_SetItem(result_list, j, value)) == -1) {
577 Py_DECREF(value);
578 goto error;
579 }
580 i++;
581 }
582 }
583 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584
585 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 Py_DECREF(result_list);
587 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000588}
589
590static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 {"register", (PyCFunction)poll_register,
592 METH_VARARGS, poll_register_doc},
593 {"modify", (PyCFunction)poll_modify,
594 METH_VARARGS, poll_modify_doc},
595 {"unregister", (PyCFunction)poll_unregister,
596 METH_O, poll_unregister_doc},
597 {"poll", (PyCFunction)poll_poll,
598 METH_VARARGS, poll_poll_doc},
599 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000600};
601
602static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000603newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 pollObject *self;
606 self = PyObject_New(pollObject, &poll_Type);
607 if (self == NULL)
608 return NULL;
609 /* ufd_uptodate is a Boolean, denoting whether the
610 array pointed to by ufds matches the contents of the dictionary. */
611 self->ufd_uptodate = 0;
612 self->ufds = NULL;
613 self->dict = PyDict_New();
614 if (self->dict == NULL) {
615 Py_DECREF(self);
616 return NULL;
617 }
618 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000619}
620
621static void
622poll_dealloc(pollObject *self)
623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 if (self->ufds != NULL)
625 PyMem_DEL(self->ufds);
626 Py_XDECREF(self->dict);
627 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628}
629
Tim Peters0c322792002-07-17 16:49:03 +0000630static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 /* The ob_type field must be initialized in the module init function
632 * to be portable to Windows without using C++. */
633 PyVarObject_HEAD_INIT(NULL, 0)
634 "select.poll", /*tp_name*/
635 sizeof(pollObject), /*tp_basicsize*/
636 0, /*tp_itemsize*/
637 /* methods */
638 (destructor)poll_dealloc, /*tp_dealloc*/
639 0, /*tp_print*/
640 0, /*tp_getattr*/
641 0, /*tp_setattr*/
642 0, /*tp_reserved*/
643 0, /*tp_repr*/
644 0, /*tp_as_number*/
645 0, /*tp_as_sequence*/
646 0, /*tp_as_mapping*/
647 0, /*tp_hash*/
648 0, /*tp_call*/
649 0, /*tp_str*/
650 0, /*tp_getattro*/
651 0, /*tp_setattro*/
652 0, /*tp_as_buffer*/
653 Py_TPFLAGS_DEFAULT, /*tp_flags*/
654 0, /*tp_doc*/
655 0, /*tp_traverse*/
656 0, /*tp_clear*/
657 0, /*tp_richcompare*/
658 0, /*tp_weaklistoffset*/
659 0, /*tp_iter*/
660 0, /*tp_iternext*/
661 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000662};
663
Jesus Cead8b9ae62011-11-14 19:07:41 +0100664#ifdef HAVE_SYS_DEVPOLL_H
665typedef struct {
666 PyObject_HEAD
667 int fd_devpoll;
668 int max_n_fds;
669 int n_fds;
670 struct pollfd *fds;
671} devpollObject;
672
673static PyTypeObject devpoll_Type;
674
675static int devpoll_flush(devpollObject *self)
676{
677 int size, n;
678
679 if (!self->n_fds) return 0;
680
681 size = sizeof(struct pollfd)*self->n_fds;
682 self->n_fds = 0;
683
684 Py_BEGIN_ALLOW_THREADS
685 n = write(self->fd_devpoll, self->fds, size);
686 Py_END_ALLOW_THREADS
687
688 if (n == -1 ) {
689 PyErr_SetFromErrno(PyExc_IOError);
690 return -1;
691 }
692 if (n < size) {
693 /*
694 ** Data writed to /dev/poll is a binary data structure. It is not
695 ** clear what to do if a partial write occurred. For now, raise
696 ** an exception and see if we actually found this problem in
697 ** the wild.
698 ** See http://bugs.python.org/issue6397.
699 */
700 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
701 "Please, report at http://bugs.python.org/. "
702 "Data to report: Size tried: %d, actual size written: %d.",
703 size, n);
704 return -1;
705 }
706 return 0;
707}
708
709static PyObject *
710internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
711{
712 PyObject *o;
713 int fd, events = POLLIN | POLLPRI | POLLOUT;
714
715 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
716 return NULL;
717 }
718
719 fd = PyObject_AsFileDescriptor(o);
720 if (fd == -1) return NULL;
721
722 if (remove) {
723 self->fds[self->n_fds].fd = fd;
724 self->fds[self->n_fds].events = POLLREMOVE;
725
726 if (++self->n_fds == self->max_n_fds) {
727 if (devpoll_flush(self))
728 return NULL;
729 }
730 }
731
732 self->fds[self->n_fds].fd = fd;
733 self->fds[self->n_fds].events = events;
734
735 if (++self->n_fds == self->max_n_fds) {
736 if (devpoll_flush(self))
737 return NULL;
738 }
739
740 Py_RETURN_NONE;
741}
742
743PyDoc_STRVAR(devpoll_register_doc,
744"register(fd [, eventmask] ) -> None\n\n\
745Register a file descriptor with the polling object.\n\
746fd -- either an integer, or an object with a fileno() method returning an\n\
747 int.\n\
748events -- an optional bitmask describing the type of events to check for");
749
750static PyObject *
751devpoll_register(devpollObject *self, PyObject *args)
752{
753 return internal_devpoll_register(self, args, 0);
754}
755
756PyDoc_STRVAR(devpoll_modify_doc,
757"modify(fd[, eventmask]) -> None\n\n\
758Modify a possible already registered file descriptor.\n\
759fd -- either an integer, or an object with a fileno() method returning an\n\
760 int.\n\
761events -- an optional bitmask describing the type of events to check for");
762
763static PyObject *
764devpoll_modify(devpollObject *self, PyObject *args)
765{
766 return internal_devpoll_register(self, args, 1);
767}
768
769
770PyDoc_STRVAR(devpoll_unregister_doc,
771"unregister(fd) -> None\n\n\
772Remove a file descriptor being tracked by the polling object.");
773
774static PyObject *
775devpoll_unregister(devpollObject *self, PyObject *o)
776{
777 int fd;
778
779 fd = PyObject_AsFileDescriptor( o );
780 if (fd == -1)
781 return NULL;
782
783 self->fds[self->n_fds].fd = fd;
784 self->fds[self->n_fds].events = POLLREMOVE;
785
786 if (++self->n_fds == self->max_n_fds) {
787 if (devpoll_flush(self))
788 return NULL;
789 }
790
791 Py_RETURN_NONE;
792}
793
794PyDoc_STRVAR(devpoll_poll_doc,
795"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
796Polls the set of registered file descriptors, returning a list containing \n\
797any descriptors that have events or errors to report.");
798
799static PyObject *
800devpoll_poll(devpollObject *self, PyObject *args)
801{
802 struct dvpoll dvp;
803 PyObject *result_list = NULL, *tout = NULL;
804 int poll_result, i;
805 long timeout;
806 PyObject *value, *num1, *num2;
807
808 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
809 return NULL;
810 }
811
812 /* Check values for timeout */
813 if (tout == NULL || tout == Py_None)
814 timeout = -1;
815 else if (!PyNumber_Check(tout)) {
816 PyErr_SetString(PyExc_TypeError,
817 "timeout must be an integer or None");
818 return NULL;
819 }
820 else {
821 tout = PyNumber_Long(tout);
822 if (!tout)
823 return NULL;
824 timeout = PyLong_AsLong(tout);
825 Py_DECREF(tout);
826 if (timeout == -1 && PyErr_Occurred())
827 return NULL;
828 }
829
830 if ((timeout < -1) || (timeout > INT_MAX)) {
831 PyErr_SetString(PyExc_OverflowError,
832 "timeout is out of range");
833 return NULL;
834 }
835
836 if (devpoll_flush(self))
837 return NULL;
838
839 dvp.dp_fds = self->fds;
840 dvp.dp_nfds = self->max_n_fds;
841 dvp.dp_timeout = timeout;
842
843 /* call devpoll() */
844 Py_BEGIN_ALLOW_THREADS
845 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
846 Py_END_ALLOW_THREADS
847
848 if (poll_result < 0) {
849 PyErr_SetFromErrno(PyExc_IOError);
850 return NULL;
851 }
852
853 /* build the result list */
854
855 result_list = PyList_New(poll_result);
856 if (!result_list)
857 return NULL;
858 else {
859 for (i = 0; i < poll_result; i++) {
860 num1 = PyLong_FromLong(self->fds[i].fd);
861 num2 = PyLong_FromLong(self->fds[i].revents);
862 if ((num1 == NULL) || (num2 == NULL)) {
863 Py_XDECREF(num1);
864 Py_XDECREF(num2);
865 goto error;
866 }
867 value = PyTuple_Pack(2, num1, num2);
868 Py_DECREF(num1);
869 Py_DECREF(num2);
870 if (value == NULL)
871 goto error;
872 if ((PyList_SetItem(result_list, i, value)) == -1) {
873 Py_DECREF(value);
874 goto error;
875 }
876 }
877 }
878
879 return result_list;
880
881 error:
882 Py_DECREF(result_list);
883 return NULL;
884}
885
886static PyMethodDef devpoll_methods[] = {
887 {"register", (PyCFunction)devpoll_register,
888 METH_VARARGS, devpoll_register_doc},
889 {"modify", (PyCFunction)devpoll_modify,
890 METH_VARARGS, devpoll_modify_doc},
891 {"unregister", (PyCFunction)devpoll_unregister,
892 METH_O, devpoll_unregister_doc},
893 {"poll", (PyCFunction)devpoll_poll,
894 METH_VARARGS, devpoll_poll_doc},
895 {NULL, NULL} /* sentinel */
896};
897
898static devpollObject *
899newDevPollObject(void)
900{
901 devpollObject *self;
902 int fd_devpoll, limit_result;
903 struct pollfd *fds;
904 struct rlimit limit;
905
906 Py_BEGIN_ALLOW_THREADS
907 /*
908 ** If we try to process more that getrlimit()
909 ** fds, the kernel will give an error, so
910 ** we set the limit here. It is a dynamic
911 ** value, because we can change rlimit() anytime.
912 */
913 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
914 if (limit_result != -1)
915 fd_devpoll = open("/dev/poll", O_RDWR);
916 Py_END_ALLOW_THREADS
917
918 if (limit_result == -1) {
919 PyErr_SetFromErrno(PyExc_OSError);
920 return NULL;
921 }
922 if (fd_devpoll == -1) {
923 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
924 return NULL;
925 }
926
927 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
928 if (fds == NULL) {
929 close(fd_devpoll);
930 PyErr_NoMemory();
931 return NULL;
932 }
933
934 self = PyObject_New(devpollObject, &devpoll_Type);
935 if (self == NULL) {
936 close(fd_devpoll);
937 PyMem_DEL(fds);
938 return NULL;
939 }
940 self->fd_devpoll = fd_devpoll;
941 self->max_n_fds = limit.rlim_cur;
942 self->n_fds = 0;
943 self->fds = fds;
944
945 return self;
946}
947
948static void
949devpoll_dealloc(devpollObject *self)
950{
951 Py_BEGIN_ALLOW_THREADS
952 close(self->fd_devpoll);
953 Py_END_ALLOW_THREADS
954
955 PyMem_DEL(self->fds);
956
957 PyObject_Del(self);
958}
959
960static PyTypeObject devpoll_Type = {
961 /* The ob_type field must be initialized in the module init function
962 * to be portable to Windows without using C++. */
963 PyVarObject_HEAD_INIT(NULL, 0)
964 "select.devpoll", /*tp_name*/
965 sizeof(devpollObject), /*tp_basicsize*/
966 0, /*tp_itemsize*/
967 /* methods */
968 (destructor)devpoll_dealloc, /*tp_dealloc*/
969 0, /*tp_print*/
970 0, /*tp_getattr*/
971 0, /*tp_setattr*/
972 0, /*tp_reserved*/
973 0, /*tp_repr*/
974 0, /*tp_as_number*/
975 0, /*tp_as_sequence*/
976 0, /*tp_as_mapping*/
977 0, /*tp_hash*/
978 0, /*tp_call*/
979 0, /*tp_str*/
980 0, /*tp_getattro*/
981 0, /*tp_setattro*/
982 0, /*tp_as_buffer*/
983 Py_TPFLAGS_DEFAULT, /*tp_flags*/
984 0, /*tp_doc*/
985 0, /*tp_traverse*/
986 0, /*tp_clear*/
987 0, /*tp_richcompare*/
988 0, /*tp_weaklistoffset*/
989 0, /*tp_iter*/
990 0, /*tp_iternext*/
991 devpoll_methods, /*tp_methods*/
992};
993#endif /* HAVE_SYS_DEVPOLL_H */
994
995
996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000997PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000998"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000999unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001000
1001static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001002select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001005}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006
Jesus Cead8b9ae62011-11-14 19:07:41 +01001007#ifdef HAVE_SYS_DEVPOLL_H
1008PyDoc_STRVAR(devpoll_doc,
1009"Returns a polling object, which supports registering and\n\
1010unregistering file descriptors, and then polling them for I/O events.");
1011
1012static PyObject *
1013select_devpoll(PyObject *self, PyObject *unused)
1014{
1015 return (PyObject *)newDevPollObject();
1016}
1017#endif
1018
1019
Thomas Wouters477c8d52006-05-27 19:21:47 +00001020#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001022 * On some systems poll() sets errno on invalid file descriptors. We test
1023 * for this at runtime because this bug may be fixed or introduced between
1024 * OS releases.
1025 */
1026static int select_have_broken_poll(void)
1027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 int poll_test;
1029 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 /* Create a file descriptor to make invalid */
1034 if (pipe(filedes) < 0) {
1035 return 1;
1036 }
1037 poll_struct.fd = filedes[0];
1038 close(filedes[0]);
1039 close(filedes[1]);
1040 poll_test = poll(&poll_struct, 1, 0);
1041 if (poll_test < 0) {
1042 return 1;
1043 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1044 return 1;
1045 }
1046 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001047}
1048#endif /* __APPLE__ */
1049
1050#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001051
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001052#ifdef HAVE_EPOLL
1053/* **************************************************************************
1054 * epoll interface for Linux 2.6
1055 *
1056 * Written by Christian Heimes
1057 * Inspired by Twisted's _epoll.pyx and select.poll()
1058 */
1059
1060#ifdef HAVE_SYS_EPOLL_H
1061#include <sys/epoll.h>
1062#endif
1063
1064typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 PyObject_HEAD
1066 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001067} pyEpoll_Object;
1068
1069static PyTypeObject pyEpoll_Type;
1070#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1071
1072static PyObject *
1073pyepoll_err_closed(void)
1074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1076 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001077}
1078
1079static int
1080pyepoll_internal_close(pyEpoll_Object *self)
1081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 int save_errno = 0;
1083 if (self->epfd >= 0) {
1084 int epfd = self->epfd;
1085 self->epfd = -1;
1086 Py_BEGIN_ALLOW_THREADS
1087 if (close(epfd) < 0)
1088 save_errno = errno;
1089 Py_END_ALLOW_THREADS
1090 }
1091 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001092}
1093
1094static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001095newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 assert(type != NULL && type->tp_alloc != NULL);
1100 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1101 if (self == NULL)
1102 return NULL;
1103
1104 if (fd == -1) {
1105 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001106#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001107 if (flags)
1108 self->epfd = epoll_create1(flags);
1109 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001110#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001111 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 Py_END_ALLOW_THREADS
1113 }
1114 else {
1115 self->epfd = fd;
1116 }
1117 if (self->epfd < 0) {
1118 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001119 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 return NULL;
1121 }
1122 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001123}
1124
1125
1126static PyObject *
1127pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1128{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001129 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001130 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001131
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001132 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1133 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001135 if (sizehint < 0) {
1136 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1137 return NULL;
1138 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001139
Benjamin Peterson95c16622011-12-27 15:36:32 -06001140 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001141}
1142
1143
1144static void
1145pyepoll_dealloc(pyEpoll_Object *self)
1146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 (void)pyepoll_internal_close(self);
1148 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001149}
1150
1151static PyObject*
1152pyepoll_close(pyEpoll_Object *self)
1153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 errno = pyepoll_internal_close(self);
1155 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001156 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 return NULL;
1158 }
1159 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001160}
1161
1162PyDoc_STRVAR(pyepoll_close_doc,
1163"close() -> None\n\
1164\n\
1165Close the epoll control file descriptor. Further operations on the epoll\n\
1166object will raise an exception.");
1167
1168static PyObject*
1169pyepoll_get_closed(pyEpoll_Object *self)
1170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 if (self->epfd < 0)
1172 Py_RETURN_TRUE;
1173 else
1174 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001175}
1176
1177static PyObject*
1178pyepoll_fileno(pyEpoll_Object *self)
1179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 if (self->epfd < 0)
1181 return pyepoll_err_closed();
1182 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001183}
1184
1185PyDoc_STRVAR(pyepoll_fileno_doc,
1186"fileno() -> int\n\
1187\n\
1188Return the epoll control file descriptor.");
1189
1190static PyObject*
1191pyepoll_fromfd(PyObject *cls, PyObject *args)
1192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1196 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001197
Benjamin Peterson95c16622011-12-27 15:36:32 -06001198 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001199}
1200
1201PyDoc_STRVAR(pyepoll_fromfd_doc,
1202"fromfd(fd) -> epoll\n\
1203\n\
1204Create an epoll object from a given control fd.");
1205
1206static PyObject *
1207pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 struct epoll_event ev;
1210 int result;
1211 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 if (epfd < 0)
1214 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 fd = PyObject_AsFileDescriptor(pfd);
1217 if (fd == -1) {
1218 return NULL;
1219 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 switch(op) {
1222 case EPOLL_CTL_ADD:
1223 case EPOLL_CTL_MOD:
1224 ev.events = events;
1225 ev.data.fd = fd;
1226 Py_BEGIN_ALLOW_THREADS
1227 result = epoll_ctl(epfd, op, fd, &ev);
1228 Py_END_ALLOW_THREADS
1229 break;
1230 case EPOLL_CTL_DEL:
1231 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1232 * operation required a non-NULL pointer in event, even
1233 * though this argument is ignored. */
1234 Py_BEGIN_ALLOW_THREADS
1235 result = epoll_ctl(epfd, op, fd, &ev);
1236 if (errno == EBADF) {
1237 /* fd already closed */
1238 result = 0;
1239 errno = 0;
1240 }
1241 Py_END_ALLOW_THREADS
1242 break;
1243 default:
1244 result = -1;
1245 errno = EINVAL;
1246 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001249 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 return NULL;
1251 }
1252 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001253}
1254
1255static PyObject *
1256pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 PyObject *pfd;
1259 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1260 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1263 &pfd, &events)) {
1264 return NULL;
1265 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001268}
1269
1270PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001271"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001272\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001273Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001274fd is the target file descriptor of the operation.\n\
1275events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001276is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1277\n\
1278The epoll interface supports all file descriptors that support poll.");
1279
1280static PyObject *
1281pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1282{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 PyObject *pfd;
1284 unsigned int events;
1285 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1288 &pfd, &events)) {
1289 return NULL;
1290 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001293}
1294
1295PyDoc_STRVAR(pyepoll_modify_doc,
1296"modify(fd, eventmask) -> None\n\
1297\n\
1298fd is the target file descriptor of the operation\n\
1299events is a bit set composed of the various EPOLL constants");
1300
1301static PyObject *
1302pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 PyObject *pfd;
1305 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1308 &pfd)) {
1309 return NULL;
1310 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001313}
1314
1315PyDoc_STRVAR(pyepoll_unregister_doc,
1316"unregister(fd) -> None\n\
1317\n\
1318fd is the target file descriptor of the operation.");
1319
1320static PyObject *
1321pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 double dtimeout = -1.;
1324 int timeout;
1325 int maxevents = -1;
1326 int nfds, i;
1327 PyObject *elist = NULL, *etuple = NULL;
1328 struct epoll_event *evs = NULL;
1329 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 if (self->epfd < 0)
1332 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1335 &dtimeout, &maxevents)) {
1336 return NULL;
1337 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 if (dtimeout < 0) {
1340 timeout = -1;
1341 }
1342 else if (dtimeout * 1000.0 > INT_MAX) {
1343 PyErr_SetString(PyExc_OverflowError,
1344 "timeout is too large");
1345 return NULL;
1346 }
1347 else {
1348 timeout = (int)(dtimeout * 1000.0);
1349 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (maxevents == -1) {
1352 maxevents = FD_SETSIZE-1;
1353 }
1354 else if (maxevents < 1) {
1355 PyErr_Format(PyExc_ValueError,
1356 "maxevents must be greater than 0, got %d",
1357 maxevents);
1358 return NULL;
1359 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 evs = PyMem_New(struct epoll_event, maxevents);
1362 if (evs == NULL) {
1363 Py_DECREF(self);
1364 PyErr_NoMemory();
1365 return NULL;
1366 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 Py_BEGIN_ALLOW_THREADS
1369 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1370 Py_END_ALLOW_THREADS
1371 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001372 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 goto error;
1374 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 elist = PyList_New(nfds);
1377 if (elist == NULL) {
1378 goto error;
1379 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 for (i = 0; i < nfds; i++) {
1382 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1383 if (etuple == NULL) {
1384 Py_CLEAR(elist);
1385 goto error;
1386 }
1387 PyList_SET_ITEM(elist, i, etuple);
1388 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389
Christian Heimesf6cd9672008-03-26 13:45:42 +00001390 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 PyMem_Free(evs);
1392 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393}
1394
1395PyDoc_STRVAR(pyepoll_poll_doc,
1396"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1397\n\
1398Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1399in seconds (as float). -1 makes poll wait indefinitely.\n\
1400Up to maxevents are returned to the caller.");
1401
1402static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 {"fromfd", (PyCFunction)pyepoll_fromfd,
1404 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1405 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1406 pyepoll_close_doc},
1407 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1408 pyepoll_fileno_doc},
1409 {"modify", (PyCFunction)pyepoll_modify,
1410 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1411 {"register", (PyCFunction)pyepoll_register,
1412 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1413 {"unregister", (PyCFunction)pyepoll_unregister,
1414 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1415 {"poll", (PyCFunction)pyepoll_poll,
1416 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1417 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418};
1419
1420static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 {"closed", (getter)pyepoll_get_closed, NULL,
1422 "True if the epoll handler is closed"},
1423 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001424};
1425
1426PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001427"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428\n\
1429Returns an epolling object\n\
1430\n\
1431sizehint must be a positive integer or -1 for the default size. The\n\
1432sizehint is used to optimize internal data structures. It doesn't limit\n\
1433the maximum number of monitored events.");
1434
1435static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 PyVarObject_HEAD_INIT(NULL, 0)
1437 "select.epoll", /* tp_name */
1438 sizeof(pyEpoll_Object), /* tp_basicsize */
1439 0, /* tp_itemsize */
1440 (destructor)pyepoll_dealloc, /* tp_dealloc */
1441 0, /* tp_print */
1442 0, /* tp_getattr */
1443 0, /* tp_setattr */
1444 0, /* tp_reserved */
1445 0, /* tp_repr */
1446 0, /* tp_as_number */
1447 0, /* tp_as_sequence */
1448 0, /* tp_as_mapping */
1449 0, /* tp_hash */
1450 0, /* tp_call */
1451 0, /* tp_str */
1452 PyObject_GenericGetAttr, /* tp_getattro */
1453 0, /* tp_setattro */
1454 0, /* tp_as_buffer */
1455 Py_TPFLAGS_DEFAULT, /* tp_flags */
1456 pyepoll_doc, /* tp_doc */
1457 0, /* tp_traverse */
1458 0, /* tp_clear */
1459 0, /* tp_richcompare */
1460 0, /* tp_weaklistoffset */
1461 0, /* tp_iter */
1462 0, /* tp_iternext */
1463 pyepoll_methods, /* tp_methods */
1464 0, /* tp_members */
1465 pyepoll_getsetlist, /* tp_getset */
1466 0, /* tp_base */
1467 0, /* tp_dict */
1468 0, /* tp_descr_get */
1469 0, /* tp_descr_set */
1470 0, /* tp_dictoffset */
1471 0, /* tp_init */
1472 0, /* tp_alloc */
1473 pyepoll_new, /* tp_new */
1474 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001475};
1476
1477#endif /* HAVE_EPOLL */
1478
1479#ifdef HAVE_KQUEUE
1480/* **************************************************************************
1481 * kqueue interface for BSD
1482 *
1483 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1484 * All rights reserved.
1485 *
1486 * Redistribution and use in source and binary forms, with or without
1487 * modification, are permitted provided that the following conditions
1488 * are met:
1489 * 1. Redistributions of source code must retain the above copyright
1490 * notice, this list of conditions and the following disclaimer.
1491 * 2. Redistributions in binary form must reproduce the above copyright
1492 * notice, this list of conditions and the following disclaimer in the
1493 * documentation and/or other materials provided with the distribution.
1494 *
1495 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1496 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1497 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1498 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1499 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1500 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1501 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1502 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1503 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1504 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1505 * SUCH DAMAGE.
1506 */
1507
1508#ifdef HAVE_SYS_EVENT_H
1509#include <sys/event.h>
1510#endif
1511
1512PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001513"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001514\n\
1515This object is the equivalent of the struct kevent for the C API.\n\
1516\n\
1517See the kqueue manpage for more detailed information about the meaning\n\
1518of the arguments.\n\
1519\n\
1520One minor note: while you might hope that udata could store a\n\
1521reference to a python object, it cannot, because it is impossible to\n\
1522keep a proper reference count of the object once it's passed into the\n\
1523kernel. Therefore, I have restricted it to only storing an integer. I\n\
1524recommend ignoring it and simply using the 'ident' field to key off\n\
1525of. You could also set up a dictionary on the python side to store a\n\
1526udata->object mapping.");
1527
1528typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 PyObject_HEAD
1530 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001531} kqueue_event_Object;
1532
1533static PyTypeObject kqueue_event_Type;
1534
1535#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1536
1537typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyObject_HEAD
1539 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001540} kqueue_queue_Object;
1541
1542static PyTypeObject kqueue_queue_Type;
1543
1544#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1545
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001546#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1547# error uintptr_t does not match void *!
1548#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1549# define T_UINTPTRT T_ULONGLONG
1550# define T_INTPTRT T_LONGLONG
1551# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1552# define UINTPTRT_FMT_UNIT "K"
1553# define INTPTRT_FMT_UNIT "L"
1554#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1555# define T_UINTPTRT T_ULONG
1556# define T_INTPTRT T_LONG
1557# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1558# define UINTPTRT_FMT_UNIT "k"
1559# define INTPTRT_FMT_UNIT "l"
1560#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1561# define T_UINTPTRT T_UINT
1562# define T_INTPTRT T_INT
1563# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1564# define UINTPTRT_FMT_UNIT "I"
1565# define INTPTRT_FMT_UNIT "i"
1566#else
1567# error uintptr_t does not match int, long, or long long!
1568#endif
1569
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001570/* Unfortunately, we can't store python objects in udata, because
1571 * kevents in the kernel can be removed without warning, which would
1572 * forever lose the refcount on the object stored with it.
1573 */
1574
1575#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1576static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1578 {"filter", T_SHORT, KQ_OFF(e.filter)},
1579 {"flags", T_USHORT, KQ_OFF(e.flags)},
1580 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1581 {"data", T_INTPTRT, KQ_OFF(e.data)},
1582 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1583 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001584};
1585#undef KQ_OFF
1586
1587static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001588
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589kqueue_event_repr(kqueue_event_Object *s)
1590{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 char buf[1024];
1592 PyOS_snprintf(
1593 buf, sizeof(buf),
1594 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1595 "data=0x%zd udata=%p>",
1596 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1597 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1598 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001599}
1600
1601static int
1602kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 PyObject *pfd;
1605 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1606 "data", "udata", NULL};
1607 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1612 &pfd, &(self->e.filter), &(self->e.flags),
1613 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1614 return -1;
1615 }
1616
1617 if (PyLong_Check(pfd)) {
1618 self->e.ident = PyLong_AsUintptr_t(pfd);
1619 }
1620 else {
1621 self->e.ident = PyObject_AsFileDescriptor(pfd);
1622 }
1623 if (PyErr_Occurred()) {
1624 return -1;
1625 }
1626 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001627}
1628
1629static PyObject *
1630kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 if (!kqueue_event_Check(o)) {
1636 if (op == Py_EQ || op == Py_NE) {
1637 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1638 Py_INCREF(res);
1639 return res;
1640 }
1641 PyErr_Format(PyExc_TypeError,
1642 "can't compare %.200s to %.200s",
1643 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1644 return NULL;
1645 }
1646 if (((result = s->e.ident - o->e.ident) == 0) &&
1647 ((result = s->e.filter - o->e.filter) == 0) &&
1648 ((result = s->e.flags - o->e.flags) == 0) &&
1649 ((result = s->e.fflags - o->e.fflags) == 0) &&
1650 ((result = s->e.data - o->e.data) == 0) &&
1651 ((result = s->e.udata - o->e.udata) == 0)
1652 ) {
1653 result = 0;
1654 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 switch (op) {
1657 case Py_EQ:
1658 result = (result == 0);
1659 break;
1660 case Py_NE:
1661 result = (result != 0);
1662 break;
1663 case Py_LE:
1664 result = (result <= 0);
1665 break;
1666 case Py_GE:
1667 result = (result >= 0);
1668 break;
1669 case Py_LT:
1670 result = (result < 0);
1671 break;
1672 case Py_GT:
1673 result = (result > 0);
1674 break;
1675 }
1676 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001677}
1678
1679static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 PyVarObject_HEAD_INIT(NULL, 0)
1681 "select.kevent", /* tp_name */
1682 sizeof(kqueue_event_Object), /* tp_basicsize */
1683 0, /* tp_itemsize */
1684 0, /* tp_dealloc */
1685 0, /* tp_print */
1686 0, /* tp_getattr */
1687 0, /* tp_setattr */
1688 0, /* tp_reserved */
1689 (reprfunc)kqueue_event_repr, /* tp_repr */
1690 0, /* tp_as_number */
1691 0, /* tp_as_sequence */
1692 0, /* tp_as_mapping */
1693 0, /* tp_hash */
1694 0, /* tp_call */
1695 0, /* tp_str */
1696 0, /* tp_getattro */
1697 0, /* tp_setattro */
1698 0, /* tp_as_buffer */
1699 Py_TPFLAGS_DEFAULT, /* tp_flags */
1700 kqueue_event_doc, /* tp_doc */
1701 0, /* tp_traverse */
1702 0, /* tp_clear */
1703 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1704 0, /* tp_weaklistoffset */
1705 0, /* tp_iter */
1706 0, /* tp_iternext */
1707 0, /* tp_methods */
1708 kqueue_event_members, /* tp_members */
1709 0, /* tp_getset */
1710 0, /* tp_base */
1711 0, /* tp_dict */
1712 0, /* tp_descr_get */
1713 0, /* tp_descr_set */
1714 0, /* tp_dictoffset */
1715 (initproc)kqueue_event_init, /* tp_init */
1716 0, /* tp_alloc */
1717 0, /* tp_new */
1718 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001719};
1720
1721static PyObject *
1722kqueue_queue_err_closed(void)
1723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1725 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001726}
1727
1728static int
1729kqueue_queue_internal_close(kqueue_queue_Object *self)
1730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 int save_errno = 0;
1732 if (self->kqfd >= 0) {
1733 int kqfd = self->kqfd;
1734 self->kqfd = -1;
1735 Py_BEGIN_ALLOW_THREADS
1736 if (close(kqfd) < 0)
1737 save_errno = errno;
1738 Py_END_ALLOW_THREADS
1739 }
1740 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741}
1742
1743static PyObject *
1744newKqueue_Object(PyTypeObject *type, SOCKET fd)
1745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 kqueue_queue_Object *self;
1747 assert(type != NULL && type->tp_alloc != NULL);
1748 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1749 if (self == NULL) {
1750 return NULL;
1751 }
1752
1753 if (fd == -1) {
1754 Py_BEGIN_ALLOW_THREADS
1755 self->kqfd = kqueue();
1756 Py_END_ALLOW_THREADS
1757 }
1758 else {
1759 self->kqfd = fd;
1760 }
1761 if (self->kqfd < 0) {
1762 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001763 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 return NULL;
1765 }
1766 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001767}
1768
1769static PyObject *
1770kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1771{
1772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 if ((args != NULL && PyObject_Size(args)) ||
1774 (kwds != NULL && PyObject_Size(kwds))) {
1775 PyErr_SetString(PyExc_ValueError,
1776 "select.kqueue doesn't accept arguments");
1777 return NULL;
1778 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001781}
1782
1783static void
1784kqueue_queue_dealloc(kqueue_queue_Object *self)
1785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 kqueue_queue_internal_close(self);
1787 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001788}
1789
1790static PyObject*
1791kqueue_queue_close(kqueue_queue_Object *self)
1792{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 errno = kqueue_queue_internal_close(self);
1794 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001795 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 return NULL;
1797 }
1798 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001799}
1800
1801PyDoc_STRVAR(kqueue_queue_close_doc,
1802"close() -> None\n\
1803\n\
1804Close the kqueue control file descriptor. Further operations on the kqueue\n\
1805object will raise an exception.");
1806
1807static PyObject*
1808kqueue_queue_get_closed(kqueue_queue_Object *self)
1809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 if (self->kqfd < 0)
1811 Py_RETURN_TRUE;
1812 else
1813 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001814}
1815
1816static PyObject*
1817kqueue_queue_fileno(kqueue_queue_Object *self)
1818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 if (self->kqfd < 0)
1820 return kqueue_queue_err_closed();
1821 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001822}
1823
1824PyDoc_STRVAR(kqueue_queue_fileno_doc,
1825"fileno() -> int\n\
1826\n\
1827Return the kqueue control file descriptor.");
1828
1829static PyObject*
1830kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1835 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001838}
1839
1840PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1841"fromfd(fd) -> kqueue\n\
1842\n\
1843Create a kqueue object from a given control fd.");
1844
1845static PyObject *
1846kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 int nevents = 0;
1849 int gotevents = 0;
1850 int nchanges = 0;
1851 int i = 0;
1852 PyObject *otimeout = NULL;
1853 PyObject *ch = NULL;
1854 PyObject *it = NULL, *ei = NULL;
1855 PyObject *result = NULL;
1856 struct kevent *evl = NULL;
1857 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001858 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (self->kqfd < 0)
1862 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1865 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 if (nevents < 0) {
1868 PyErr_Format(PyExc_ValueError,
1869 "Length of eventlist must be 0 or positive, got %d",
1870 nevents);
1871 return NULL;
1872 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 if (otimeout == Py_None || otimeout == NULL) {
1875 ptimeoutspec = NULL;
1876 }
1877 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001878 if (_PyTime_ObjectToTimespec(otimeout,
1879 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1880 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001881
Victor Stinner5d272cc2012-03-13 13:35:55 +01001882 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 PyErr_SetString(PyExc_ValueError,
1884 "timeout must be positive or None");
1885 return NULL;
1886 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001887 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 }
1889 else {
1890 PyErr_Format(PyExc_TypeError,
1891 "timeout argument must be an number "
1892 "or None, got %.200s",
1893 Py_TYPE(otimeout)->tp_name);
1894 return NULL;
1895 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (ch != NULL && ch != Py_None) {
1898 it = PyObject_GetIter(ch);
1899 if (it == NULL) {
1900 PyErr_SetString(PyExc_TypeError,
1901 "changelist is not iterable");
1902 return NULL;
1903 }
1904 nchanges = PyObject_Size(ch);
1905 if (nchanges < 0) {
1906 goto error;
1907 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 chl = PyMem_New(struct kevent, nchanges);
1910 if (chl == NULL) {
1911 PyErr_NoMemory();
1912 goto error;
1913 }
1914 i = 0;
1915 while ((ei = PyIter_Next(it)) != NULL) {
1916 if (!kqueue_event_Check(ei)) {
1917 Py_DECREF(ei);
1918 PyErr_SetString(PyExc_TypeError,
1919 "changelist must be an iterable of "
1920 "select.kevent objects");
1921 goto error;
1922 } else {
1923 chl[i++] = ((kqueue_event_Object *)ei)->e;
1924 }
1925 Py_DECREF(ei);
1926 }
1927 }
1928 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 /* event list */
1931 if (nevents) {
1932 evl = PyMem_New(struct kevent, nevents);
1933 if (evl == NULL) {
1934 PyErr_NoMemory();
1935 goto error;
1936 }
1937 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 Py_BEGIN_ALLOW_THREADS
1940 gotevents = kevent(self->kqfd, chl, nchanges,
1941 evl, nevents, ptimeoutspec);
1942 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 if (gotevents == -1) {
1945 PyErr_SetFromErrno(PyExc_OSError);
1946 goto error;
1947 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 result = PyList_New(gotevents);
1950 if (result == NULL) {
1951 goto error;
1952 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 for (i = 0; i < gotevents; i++) {
1955 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1958 if (ch == NULL) {
1959 goto error;
1960 }
1961 ch->e = evl[i];
1962 PyList_SET_ITEM(result, i, (PyObject *)ch);
1963 }
1964 PyMem_Free(chl);
1965 PyMem_Free(evl);
1966 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001967
1968 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 PyMem_Free(chl);
1970 PyMem_Free(evl);
1971 Py_XDECREF(result);
1972 Py_XDECREF(it);
1973 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001974}
1975
1976PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001977"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001978\n\
1979Calls the kernel kevent function.\n\
1980- changelist must be a list of kevent objects describing the changes\n\
1981 to be made to the kernel's watch list or None.\n\
1982- max_events lets you specify the maximum number of events that the\n\
1983 kernel will return.\n\
1984- timeout is the maximum time to wait in seconds, or else None,\n\
1985 to wait forever. timeout accepts floats for smaller timeouts, too.");
1986
1987
1988static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1990 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1991 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1992 kqueue_queue_close_doc},
1993 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1994 kqueue_queue_fileno_doc},
1995 {"control", (PyCFunction)kqueue_queue_control,
1996 METH_VARARGS , kqueue_queue_control_doc},
1997 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001998};
1999
2000static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 {"closed", (getter)kqueue_queue_get_closed, NULL,
2002 "True if the kqueue handler is closed"},
2003 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002004};
2005
2006PyDoc_STRVAR(kqueue_queue_doc,
2007"Kqueue syscall wrapper.\n\
2008\n\
2009For example, to start watching a socket for input:\n\
2010>>> kq = kqueue()\n\
2011>>> sock = socket()\n\
2012>>> sock.connect((host, port))\n\
2013>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2014\n\
2015To wait one second for it to become writeable:\n\
2016>>> kq.control(None, 1, 1000)\n\
2017\n\
2018To stop listening:\n\
2019>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2020
2021static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 PyVarObject_HEAD_INIT(NULL, 0)
2023 "select.kqueue", /* tp_name */
2024 sizeof(kqueue_queue_Object), /* tp_basicsize */
2025 0, /* tp_itemsize */
2026 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2027 0, /* tp_print */
2028 0, /* tp_getattr */
2029 0, /* tp_setattr */
2030 0, /* tp_reserved */
2031 0, /* tp_repr */
2032 0, /* tp_as_number */
2033 0, /* tp_as_sequence */
2034 0, /* tp_as_mapping */
2035 0, /* tp_hash */
2036 0, /* tp_call */
2037 0, /* tp_str */
2038 0, /* tp_getattro */
2039 0, /* tp_setattro */
2040 0, /* tp_as_buffer */
2041 Py_TPFLAGS_DEFAULT, /* tp_flags */
2042 kqueue_queue_doc, /* tp_doc */
2043 0, /* tp_traverse */
2044 0, /* tp_clear */
2045 0, /* tp_richcompare */
2046 0, /* tp_weaklistoffset */
2047 0, /* tp_iter */
2048 0, /* tp_iternext */
2049 kqueue_queue_methods, /* tp_methods */
2050 0, /* tp_members */
2051 kqueue_queue_getsetlist, /* tp_getset */
2052 0, /* tp_base */
2053 0, /* tp_dict */
2054 0, /* tp_descr_get */
2055 0, /* tp_descr_set */
2056 0, /* tp_dictoffset */
2057 0, /* tp_init */
2058 0, /* tp_alloc */
2059 kqueue_queue_new, /* tp_new */
2060 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002061};
2062
2063#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002064
2065
2066
2067
2068
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002069/* ************************************************************************ */
2070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002072"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2073\n\
2074Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002075The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002076rlist -- wait until ready for reading\n\
2077wlist -- wait until ready for writing\n\
2078xlist -- wait for an ``exceptional condition''\n\
2079If only one kind of condition is required, pass [] for the other lists.\n\
2080A file descriptor is either a socket or file object, or a small integer\n\
2081gotten from a fileno() method call on one of those.\n\
2082\n\
2083The optional 4th argument specifies a timeout in seconds; it may be\n\
2084a floating point number to specify fractions of seconds. If it is absent\n\
2085or None, the call will never time out.\n\
2086\n\
2087The return value is a tuple of three lists corresponding to the first three\n\
2088arguments; each contains the subset of the corresponding file descriptors\n\
2089that are ready.\n\
2090\n\
2091*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002092On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002093descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002094
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002095static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002097#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002099#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002100#ifdef HAVE_SYS_DEVPOLL_H
2101 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2102#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002104};
2105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002106PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002107"This module supports asynchronous I/O on multiple file descriptors.\n\
2108\n\
2109*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002110On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002111
Martin v. Löwis1a214512008-06-11 05:26:20 +00002112
2113static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 PyModuleDef_HEAD_INIT,
2115 "select",
2116 module_doc,
2117 -1,
2118 select_methods,
2119 NULL,
2120 NULL,
2121 NULL,
2122 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002123};
2124
Jesus Cead8b9ae62011-11-14 19:07:41 +01002125
2126
2127
Mark Hammond62b1ab12002-07-23 06:31:15 +00002128PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002129PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 PyObject *m;
2132 m = PyModule_Create(&selectmodule);
2133 if (m == NULL)
2134 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002135
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002136 Py_INCREF(PyExc_OSError);
2137 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002138
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002139#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002140#ifdef HAVE_BROKEN_PIPE_BUF
2141#undef PIPE_BUF
2142#define PIPE_BUF 512
2143#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002145#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002146
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002147#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002148#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 if (select_have_broken_poll()) {
2150 if (PyObject_DelAttrString(m, "poll") == -1) {
2151 PyErr_Clear();
2152 }
2153 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002154#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002156#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 if (PyType_Ready(&poll_Type) < 0)
2158 return NULL;
2159 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2160 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2161 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2162 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2163 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2164 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002165
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002166#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002168#endif
2169#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002171#endif
2172#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002174#endif
2175#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002177#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002178#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002180#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002182#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002183
Jesus Cead8b9ae62011-11-14 19:07:41 +01002184#ifdef HAVE_SYS_DEVPOLL_H
2185 if (PyType_Ready(&devpoll_Type) < 0)
2186 return NULL;
2187#endif
2188
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002189#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2191 if (PyType_Ready(&pyEpoll_Type) < 0)
2192 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 Py_INCREF(&pyEpoll_Type);
2195 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2198 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2199 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2200 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2201 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2202 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002203#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 /* Kernel 2.6.2+ */
2205 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002206#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002207 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2208 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2209 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2210 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2211 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2212 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002213
Benjamin Peterson95c16622011-12-27 15:36:32 -06002214#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002215 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002216#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002217#endif /* HAVE_EPOLL */
2218
2219#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 kqueue_event_Type.tp_new = PyType_GenericNew;
2221 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2222 if(PyType_Ready(&kqueue_event_Type) < 0)
2223 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 Py_INCREF(&kqueue_event_Type);
2226 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2229 if(PyType_Ready(&kqueue_queue_Type) < 0)
2230 return NULL;
2231 Py_INCREF(&kqueue_queue_Type);
2232 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2233
2234 /* event filters */
2235 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2236 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2237 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2238 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2239 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002240#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2244 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 /* event flags */
2247 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2248 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2249 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2250 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2251 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2252 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2255 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2258 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 /* READ WRITE filter flag */
2261 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 /* VNODE filter flags */
2264 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2265 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2266 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2267 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2268 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2269 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 /* PROC filter flags */
2273 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2274 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2275 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2276 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2277 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2280 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2281 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2282
2283 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002284#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2286 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2287 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002288#endif
2289
2290#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002292}