blob: 06abcf1ac3ce4abdd2df094dfba26c8ac11ad923 [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)) {
Serhiy Storchaka441d30f2013-01-19 12:26:26 +0200360 assert(i < self->ufd_len);
361 /* Never overflow */
362 self->ufds[i].fd = (int)PyLong_AsLong(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 self->ufds[i].events = (short)PyLong_AsLong(value);
364 i++;
365 }
Serhiy Storchaka441d30f2013-01-19 12:26:26 +0200366 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 self->ufd_uptodate = 1;
368 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369}
370
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000371PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000372"register(fd [, eventmask] ) -> None\n\n\
373Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000374fd -- either an integer, or an object with a fileno() method returning an\n\
375 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000376events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000377
378static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 PyObject *o, *key, *value;
Serhiy Storchaka441d30f2013-01-19 12:26:26 +0200382 int fd;
383 short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000385
Serhiy Storchaka441d30f2013-01-19 12:26:26 +0200386 if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 return NULL;
388 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 fd = PyObject_AsFileDescriptor(o);
391 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 /* Add entry to the internal dictionary: the key is the
394 file descriptor, and the value is the event mask. */
395 key = PyLong_FromLong(fd);
396 if (key == NULL)
397 return NULL;
398 value = PyLong_FromLong(events);
399 if (value == NULL) {
400 Py_DECREF(key);
401 return NULL;
402 }
403 err = PyDict_SetItem(self->dict, key, value);
404 Py_DECREF(key);
405 Py_DECREF(value);
406 if (err < 0)
407 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 self->ufd_uptodate = 0;
410
411 Py_INCREF(Py_None);
412 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000413}
414
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000415PyDoc_STRVAR(poll_modify_doc,
416"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000417Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000418fd -- either an integer, or an object with a fileno() method returning an\n\
419 int.\n\
420events -- an optional bitmask describing the type of events to check for");
421
422static PyObject *
423poll_modify(pollObject *self, PyObject *args)
424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 PyObject *o, *key, *value;
426 int fd, events;
427 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
430 return NULL;
431 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 fd = PyObject_AsFileDescriptor(o);
434 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 /* Modify registered fd */
437 key = PyLong_FromLong(fd);
438 if (key == NULL)
439 return NULL;
440 if (PyDict_GetItem(self->dict, key) == NULL) {
441 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200442 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200443 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 return NULL;
445 }
446 value = PyLong_FromLong(events);
447 if (value == NULL) {
448 Py_DECREF(key);
449 return NULL;
450 }
451 err = PyDict_SetItem(self->dict, key, value);
452 Py_DECREF(key);
453 Py_DECREF(value);
454 if (err < 0)
455 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 self->ufd_uptodate = 0;
458
459 Py_INCREF(Py_None);
460 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000461}
462
463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000464PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000466Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000467
468static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 PyObject *key;
472 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 fd = PyObject_AsFileDescriptor( o );
475 if (fd == -1)
476 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 /* Check whether the fd is already in the array */
479 key = PyLong_FromLong(fd);
480 if (key == NULL)
481 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 if (PyDict_DelItem(self->dict, key) == -1) {
484 Py_DECREF(key);
485 /* This will simply raise the KeyError set by PyDict_DelItem
486 if the file descriptor isn't registered. */
487 return NULL;
488 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 Py_DECREF(key);
491 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 Py_INCREF(Py_None);
494 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495}
496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000497PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
499Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000500any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000501
502static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 PyObject *result_list = NULL, *tout = NULL;
506 int timeout = 0, poll_result, i, j;
507 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
510 return NULL;
511 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 /* Check values for timeout */
514 if (tout == NULL || tout == Py_None)
515 timeout = -1;
516 else if (!PyNumber_Check(tout)) {
517 PyErr_SetString(PyExc_TypeError,
518 "timeout must be an integer or None");
519 return NULL;
520 }
521 else {
522 tout = PyNumber_Long(tout);
523 if (!tout)
524 return NULL;
Serhiy Storchaka441d30f2013-01-19 12:26:26 +0200525 timeout = _PyLong_AsInt(tout);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 Py_DECREF(tout);
527 if (timeout == -1 && PyErr_Occurred())
528 return NULL;
529 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 /* Ensure the ufd array is up to date */
532 if (!self->ufd_uptodate)
533 if (update_ufd_array(self) == 0)
534 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 /* call poll() */
537 Py_BEGIN_ALLOW_THREADS
538 poll_result = poll(self->ufds, self->ufd_len, timeout);
539 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200542 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 return NULL;
544 }
545
546 /* build the result list */
547
548 result_list = PyList_New(poll_result);
549 if (!result_list)
550 return NULL;
551 else {
552 for (i = 0, j = 0; j < poll_result; j++) {
553 /* skip to the next fired descriptor */
554 while (!self->ufds[i].revents) {
555 i++;
556 }
557 /* if we hit a NULL return, set value to NULL
558 and break out of loop; code at end will
559 clean up result_list */
560 value = PyTuple_New(2);
561 if (value == NULL)
562 goto error;
563 num = PyLong_FromLong(self->ufds[i].fd);
564 if (num == NULL) {
565 Py_DECREF(value);
566 goto error;
567 }
568 PyTuple_SET_ITEM(value, 0, num);
569
570 /* The &0xffff is a workaround for AIX. 'revents'
571 is a 16-bit short, and IBM assigned POLLNVAL
572 to be 0x8000, so the conversion to int results
573 in a negative number. See SF bug #923315. */
574 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
575 if (num == NULL) {
576 Py_DECREF(value);
577 goto error;
578 }
579 PyTuple_SET_ITEM(value, 1, num);
580 if ((PyList_SetItem(result_list, j, value)) == -1) {
581 Py_DECREF(value);
582 goto error;
583 }
584 i++;
585 }
586 }
587 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000588
589 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 Py_DECREF(result_list);
591 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000592}
593
594static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 {"register", (PyCFunction)poll_register,
596 METH_VARARGS, poll_register_doc},
597 {"modify", (PyCFunction)poll_modify,
598 METH_VARARGS, poll_modify_doc},
599 {"unregister", (PyCFunction)poll_unregister,
600 METH_O, poll_unregister_doc},
601 {"poll", (PyCFunction)poll_poll,
602 METH_VARARGS, poll_poll_doc},
603 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604};
605
606static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000607newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000608{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 pollObject *self;
610 self = PyObject_New(pollObject, &poll_Type);
611 if (self == NULL)
612 return NULL;
613 /* ufd_uptodate is a Boolean, denoting whether the
614 array pointed to by ufds matches the contents of the dictionary. */
615 self->ufd_uptodate = 0;
616 self->ufds = NULL;
617 self->dict = PyDict_New();
618 if (self->dict == NULL) {
619 Py_DECREF(self);
620 return NULL;
621 }
622 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623}
624
625static void
626poll_dealloc(pollObject *self)
627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 if (self->ufds != NULL)
629 PyMem_DEL(self->ufds);
630 Py_XDECREF(self->dict);
631 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000632}
633
Tim Peters0c322792002-07-17 16:49:03 +0000634static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 /* The ob_type field must be initialized in the module init function
636 * to be portable to Windows without using C++. */
637 PyVarObject_HEAD_INIT(NULL, 0)
638 "select.poll", /*tp_name*/
639 sizeof(pollObject), /*tp_basicsize*/
640 0, /*tp_itemsize*/
641 /* methods */
642 (destructor)poll_dealloc, /*tp_dealloc*/
643 0, /*tp_print*/
644 0, /*tp_getattr*/
645 0, /*tp_setattr*/
646 0, /*tp_reserved*/
647 0, /*tp_repr*/
648 0, /*tp_as_number*/
649 0, /*tp_as_sequence*/
650 0, /*tp_as_mapping*/
651 0, /*tp_hash*/
652 0, /*tp_call*/
653 0, /*tp_str*/
654 0, /*tp_getattro*/
655 0, /*tp_setattro*/
656 0, /*tp_as_buffer*/
657 Py_TPFLAGS_DEFAULT, /*tp_flags*/
658 0, /*tp_doc*/
659 0, /*tp_traverse*/
660 0, /*tp_clear*/
661 0, /*tp_richcompare*/
662 0, /*tp_weaklistoffset*/
663 0, /*tp_iter*/
664 0, /*tp_iternext*/
665 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000666};
667
Jesus Cead8b9ae62011-11-14 19:07:41 +0100668#ifdef HAVE_SYS_DEVPOLL_H
669typedef struct {
670 PyObject_HEAD
671 int fd_devpoll;
672 int max_n_fds;
673 int n_fds;
674 struct pollfd *fds;
675} devpollObject;
676
677static PyTypeObject devpoll_Type;
678
679static int devpoll_flush(devpollObject *self)
680{
681 int size, n;
682
683 if (!self->n_fds) return 0;
684
685 size = sizeof(struct pollfd)*self->n_fds;
686 self->n_fds = 0;
687
688 Py_BEGIN_ALLOW_THREADS
689 n = write(self->fd_devpoll, self->fds, size);
690 Py_END_ALLOW_THREADS
691
692 if (n == -1 ) {
693 PyErr_SetFromErrno(PyExc_IOError);
694 return -1;
695 }
696 if (n < size) {
697 /*
698 ** Data writed to /dev/poll is a binary data structure. It is not
699 ** clear what to do if a partial write occurred. For now, raise
700 ** an exception and see if we actually found this problem in
701 ** the wild.
702 ** See http://bugs.python.org/issue6397.
703 */
704 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
705 "Please, report at http://bugs.python.org/. "
706 "Data to report: Size tried: %d, actual size written: %d.",
707 size, n);
708 return -1;
709 }
710 return 0;
711}
712
713static PyObject *
714internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
715{
716 PyObject *o;
717 int fd, events = POLLIN | POLLPRI | POLLOUT;
718
719 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
720 return NULL;
721 }
722
723 fd = PyObject_AsFileDescriptor(o);
724 if (fd == -1) return NULL;
725
726 if (remove) {
727 self->fds[self->n_fds].fd = fd;
728 self->fds[self->n_fds].events = POLLREMOVE;
729
730 if (++self->n_fds == self->max_n_fds) {
731 if (devpoll_flush(self))
732 return NULL;
733 }
734 }
735
736 self->fds[self->n_fds].fd = fd;
737 self->fds[self->n_fds].events = events;
738
739 if (++self->n_fds == self->max_n_fds) {
740 if (devpoll_flush(self))
741 return NULL;
742 }
743
744 Py_RETURN_NONE;
745}
746
747PyDoc_STRVAR(devpoll_register_doc,
748"register(fd [, eventmask] ) -> None\n\n\
749Register a file descriptor with the polling object.\n\
750fd -- either an integer, or an object with a fileno() method returning an\n\
751 int.\n\
752events -- an optional bitmask describing the type of events to check for");
753
754static PyObject *
755devpoll_register(devpollObject *self, PyObject *args)
756{
757 return internal_devpoll_register(self, args, 0);
758}
759
760PyDoc_STRVAR(devpoll_modify_doc,
761"modify(fd[, eventmask]) -> None\n\n\
762Modify a possible already registered file descriptor.\n\
763fd -- either an integer, or an object with a fileno() method returning an\n\
764 int.\n\
765events -- an optional bitmask describing the type of events to check for");
766
767static PyObject *
768devpoll_modify(devpollObject *self, PyObject *args)
769{
770 return internal_devpoll_register(self, args, 1);
771}
772
773
774PyDoc_STRVAR(devpoll_unregister_doc,
775"unregister(fd) -> None\n\n\
776Remove a file descriptor being tracked by the polling object.");
777
778static PyObject *
779devpoll_unregister(devpollObject *self, PyObject *o)
780{
781 int fd;
782
783 fd = PyObject_AsFileDescriptor( o );
784 if (fd == -1)
785 return NULL;
786
787 self->fds[self->n_fds].fd = fd;
788 self->fds[self->n_fds].events = POLLREMOVE;
789
790 if (++self->n_fds == self->max_n_fds) {
791 if (devpoll_flush(self))
792 return NULL;
793 }
794
795 Py_RETURN_NONE;
796}
797
798PyDoc_STRVAR(devpoll_poll_doc,
799"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
800Polls the set of registered file descriptors, returning a list containing \n\
801any descriptors that have events or errors to report.");
802
803static PyObject *
804devpoll_poll(devpollObject *self, PyObject *args)
805{
806 struct dvpoll dvp;
807 PyObject *result_list = NULL, *tout = NULL;
808 int poll_result, i;
809 long timeout;
810 PyObject *value, *num1, *num2;
811
812 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
813 return NULL;
814 }
815
816 /* Check values for timeout */
817 if (tout == NULL || tout == Py_None)
818 timeout = -1;
819 else if (!PyNumber_Check(tout)) {
820 PyErr_SetString(PyExc_TypeError,
821 "timeout must be an integer or None");
822 return NULL;
823 }
824 else {
825 tout = PyNumber_Long(tout);
826 if (!tout)
827 return NULL;
828 timeout = PyLong_AsLong(tout);
829 Py_DECREF(tout);
830 if (timeout == -1 && PyErr_Occurred())
831 return NULL;
832 }
833
834 if ((timeout < -1) || (timeout > INT_MAX)) {
835 PyErr_SetString(PyExc_OverflowError,
836 "timeout is out of range");
837 return NULL;
838 }
839
840 if (devpoll_flush(self))
841 return NULL;
842
843 dvp.dp_fds = self->fds;
844 dvp.dp_nfds = self->max_n_fds;
845 dvp.dp_timeout = timeout;
846
847 /* call devpoll() */
848 Py_BEGIN_ALLOW_THREADS
849 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
850 Py_END_ALLOW_THREADS
851
852 if (poll_result < 0) {
853 PyErr_SetFromErrno(PyExc_IOError);
854 return NULL;
855 }
856
857 /* build the result list */
858
859 result_list = PyList_New(poll_result);
860 if (!result_list)
861 return NULL;
862 else {
863 for (i = 0; i < poll_result; i++) {
864 num1 = PyLong_FromLong(self->fds[i].fd);
865 num2 = PyLong_FromLong(self->fds[i].revents);
866 if ((num1 == NULL) || (num2 == NULL)) {
867 Py_XDECREF(num1);
868 Py_XDECREF(num2);
869 goto error;
870 }
871 value = PyTuple_Pack(2, num1, num2);
872 Py_DECREF(num1);
873 Py_DECREF(num2);
874 if (value == NULL)
875 goto error;
876 if ((PyList_SetItem(result_list, i, value)) == -1) {
877 Py_DECREF(value);
878 goto error;
879 }
880 }
881 }
882
883 return result_list;
884
885 error:
886 Py_DECREF(result_list);
887 return NULL;
888}
889
890static PyMethodDef devpoll_methods[] = {
891 {"register", (PyCFunction)devpoll_register,
892 METH_VARARGS, devpoll_register_doc},
893 {"modify", (PyCFunction)devpoll_modify,
894 METH_VARARGS, devpoll_modify_doc},
895 {"unregister", (PyCFunction)devpoll_unregister,
896 METH_O, devpoll_unregister_doc},
897 {"poll", (PyCFunction)devpoll_poll,
898 METH_VARARGS, devpoll_poll_doc},
899 {NULL, NULL} /* sentinel */
900};
901
902static devpollObject *
903newDevPollObject(void)
904{
905 devpollObject *self;
906 int fd_devpoll, limit_result;
907 struct pollfd *fds;
908 struct rlimit limit;
909
910 Py_BEGIN_ALLOW_THREADS
911 /*
912 ** If we try to process more that getrlimit()
913 ** fds, the kernel will give an error, so
914 ** we set the limit here. It is a dynamic
915 ** value, because we can change rlimit() anytime.
916 */
917 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
918 if (limit_result != -1)
919 fd_devpoll = open("/dev/poll", O_RDWR);
920 Py_END_ALLOW_THREADS
921
922 if (limit_result == -1) {
923 PyErr_SetFromErrno(PyExc_OSError);
924 return NULL;
925 }
926 if (fd_devpoll == -1) {
927 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
928 return NULL;
929 }
930
931 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
932 if (fds == NULL) {
933 close(fd_devpoll);
934 PyErr_NoMemory();
935 return NULL;
936 }
937
938 self = PyObject_New(devpollObject, &devpoll_Type);
939 if (self == NULL) {
940 close(fd_devpoll);
941 PyMem_DEL(fds);
942 return NULL;
943 }
944 self->fd_devpoll = fd_devpoll;
945 self->max_n_fds = limit.rlim_cur;
946 self->n_fds = 0;
947 self->fds = fds;
948
949 return self;
950}
951
952static void
953devpoll_dealloc(devpollObject *self)
954{
955 Py_BEGIN_ALLOW_THREADS
956 close(self->fd_devpoll);
957 Py_END_ALLOW_THREADS
958
959 PyMem_DEL(self->fds);
960
961 PyObject_Del(self);
962}
963
964static PyTypeObject devpoll_Type = {
965 /* The ob_type field must be initialized in the module init function
966 * to be portable to Windows without using C++. */
967 PyVarObject_HEAD_INIT(NULL, 0)
968 "select.devpoll", /*tp_name*/
969 sizeof(devpollObject), /*tp_basicsize*/
970 0, /*tp_itemsize*/
971 /* methods */
972 (destructor)devpoll_dealloc, /*tp_dealloc*/
973 0, /*tp_print*/
974 0, /*tp_getattr*/
975 0, /*tp_setattr*/
976 0, /*tp_reserved*/
977 0, /*tp_repr*/
978 0, /*tp_as_number*/
979 0, /*tp_as_sequence*/
980 0, /*tp_as_mapping*/
981 0, /*tp_hash*/
982 0, /*tp_call*/
983 0, /*tp_str*/
984 0, /*tp_getattro*/
985 0, /*tp_setattro*/
986 0, /*tp_as_buffer*/
987 Py_TPFLAGS_DEFAULT, /*tp_flags*/
988 0, /*tp_doc*/
989 0, /*tp_traverse*/
990 0, /*tp_clear*/
991 0, /*tp_richcompare*/
992 0, /*tp_weaklistoffset*/
993 0, /*tp_iter*/
994 0, /*tp_iternext*/
995 devpoll_methods, /*tp_methods*/
996};
997#endif /* HAVE_SYS_DEVPOLL_H */
998
999
1000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001001PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001002"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001003unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001004
1005static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001006select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001009}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001010
Jesus Cead8b9ae62011-11-14 19:07:41 +01001011#ifdef HAVE_SYS_DEVPOLL_H
1012PyDoc_STRVAR(devpoll_doc,
1013"Returns a polling object, which supports registering and\n\
1014unregistering file descriptors, and then polling them for I/O events.");
1015
1016static PyObject *
1017select_devpoll(PyObject *self, PyObject *unused)
1018{
1019 return (PyObject *)newDevPollObject();
1020}
1021#endif
1022
1023
Thomas Wouters477c8d52006-05-27 19:21:47 +00001024#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001026 * On some systems poll() sets errno on invalid file descriptors. We test
1027 * for this at runtime because this bug may be fixed or introduced between
1028 * OS releases.
1029 */
1030static int select_have_broken_poll(void)
1031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 int poll_test;
1033 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 /* Create a file descriptor to make invalid */
1038 if (pipe(filedes) < 0) {
1039 return 1;
1040 }
1041 poll_struct.fd = filedes[0];
1042 close(filedes[0]);
1043 close(filedes[1]);
1044 poll_test = poll(&poll_struct, 1, 0);
1045 if (poll_test < 0) {
1046 return 1;
1047 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1048 return 1;
1049 }
1050 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051}
1052#endif /* __APPLE__ */
1053
1054#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001055
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001056#ifdef HAVE_EPOLL
1057/* **************************************************************************
1058 * epoll interface for Linux 2.6
1059 *
1060 * Written by Christian Heimes
1061 * Inspired by Twisted's _epoll.pyx and select.poll()
1062 */
1063
1064#ifdef HAVE_SYS_EPOLL_H
1065#include <sys/epoll.h>
1066#endif
1067
1068typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 PyObject_HEAD
1070 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001071} pyEpoll_Object;
1072
1073static PyTypeObject pyEpoll_Type;
1074#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1075
1076static PyObject *
1077pyepoll_err_closed(void)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1080 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001081}
1082
1083static int
1084pyepoll_internal_close(pyEpoll_Object *self)
1085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 int save_errno = 0;
1087 if (self->epfd >= 0) {
1088 int epfd = self->epfd;
1089 self->epfd = -1;
1090 Py_BEGIN_ALLOW_THREADS
1091 if (close(epfd) < 0)
1092 save_errno = errno;
1093 Py_END_ALLOW_THREADS
1094 }
1095 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001096}
1097
1098static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001099newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 assert(type != NULL && type->tp_alloc != NULL);
1104 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1105 if (self == NULL)
1106 return NULL;
1107
1108 if (fd == -1) {
1109 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001110#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001111 if (flags)
1112 self->epfd = epoll_create1(flags);
1113 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001114#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001115 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 Py_END_ALLOW_THREADS
1117 }
1118 else {
1119 self->epfd = fd;
1120 }
1121 if (self->epfd < 0) {
1122 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001123 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 return NULL;
1125 }
1126 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001127}
1128
1129
1130static PyObject *
1131pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1132{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001133 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001134 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001135
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001136 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1137 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001139 if (sizehint < 0) {
1140 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1141 return NULL;
1142 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001143
Benjamin Peterson95c16622011-12-27 15:36:32 -06001144 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001145}
1146
1147
1148static void
1149pyepoll_dealloc(pyEpoll_Object *self)
1150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 (void)pyepoll_internal_close(self);
1152 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001153}
1154
1155static PyObject*
1156pyepoll_close(pyEpoll_Object *self)
1157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 errno = pyepoll_internal_close(self);
1159 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001160 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 return NULL;
1162 }
1163 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001164}
1165
1166PyDoc_STRVAR(pyepoll_close_doc,
1167"close() -> None\n\
1168\n\
1169Close the epoll control file descriptor. Further operations on the epoll\n\
1170object will raise an exception.");
1171
1172static PyObject*
1173pyepoll_get_closed(pyEpoll_Object *self)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 if (self->epfd < 0)
1176 Py_RETURN_TRUE;
1177 else
1178 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001179}
1180
1181static PyObject*
1182pyepoll_fileno(pyEpoll_Object *self)
1183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 if (self->epfd < 0)
1185 return pyepoll_err_closed();
1186 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001187}
1188
1189PyDoc_STRVAR(pyepoll_fileno_doc,
1190"fileno() -> int\n\
1191\n\
1192Return the epoll control file descriptor.");
1193
1194static PyObject*
1195pyepoll_fromfd(PyObject *cls, PyObject *args)
1196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1200 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001201
Benjamin Peterson95c16622011-12-27 15:36:32 -06001202 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001203}
1204
1205PyDoc_STRVAR(pyepoll_fromfd_doc,
1206"fromfd(fd) -> epoll\n\
1207\n\
1208Create an epoll object from a given control fd.");
1209
1210static PyObject *
1211pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 struct epoll_event ev;
1214 int result;
1215 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 if (epfd < 0)
1218 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 fd = PyObject_AsFileDescriptor(pfd);
1221 if (fd == -1) {
1222 return NULL;
1223 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 switch(op) {
1226 case EPOLL_CTL_ADD:
1227 case EPOLL_CTL_MOD:
1228 ev.events = events;
1229 ev.data.fd = fd;
1230 Py_BEGIN_ALLOW_THREADS
1231 result = epoll_ctl(epfd, op, fd, &ev);
1232 Py_END_ALLOW_THREADS
1233 break;
1234 case EPOLL_CTL_DEL:
1235 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1236 * operation required a non-NULL pointer in event, even
1237 * though this argument is ignored. */
1238 Py_BEGIN_ALLOW_THREADS
1239 result = epoll_ctl(epfd, op, fd, &ev);
1240 if (errno == EBADF) {
1241 /* fd already closed */
1242 result = 0;
1243 errno = 0;
1244 }
1245 Py_END_ALLOW_THREADS
1246 break;
1247 default:
1248 result = -1;
1249 errno = EINVAL;
1250 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001253 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return NULL;
1255 }
1256 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001257}
1258
1259static PyObject *
1260pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PyObject *pfd;
1263 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1264 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1267 &pfd, &events)) {
1268 return NULL;
1269 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001272}
1273
1274PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001275"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001276\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001277Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001278fd is the target file descriptor of the operation.\n\
1279events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001280is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1281\n\
1282The epoll interface supports all file descriptors that support poll.");
1283
1284static PyObject *
1285pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 PyObject *pfd;
1288 unsigned int events;
1289 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1292 &pfd, &events)) {
1293 return NULL;
1294 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001297}
1298
1299PyDoc_STRVAR(pyepoll_modify_doc,
1300"modify(fd, eventmask) -> None\n\
1301\n\
1302fd is the target file descriptor of the operation\n\
1303events is a bit set composed of the various EPOLL constants");
1304
1305static PyObject *
1306pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyObject *pfd;
1309 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1312 &pfd)) {
1313 return NULL;
1314 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001317}
1318
1319PyDoc_STRVAR(pyepoll_unregister_doc,
1320"unregister(fd) -> None\n\
1321\n\
1322fd is the target file descriptor of the operation.");
1323
1324static PyObject *
1325pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 double dtimeout = -1.;
1328 int timeout;
1329 int maxevents = -1;
1330 int nfds, i;
1331 PyObject *elist = NULL, *etuple = NULL;
1332 struct epoll_event *evs = NULL;
1333 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 if (self->epfd < 0)
1336 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1339 &dtimeout, &maxevents)) {
1340 return NULL;
1341 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if (dtimeout < 0) {
1344 timeout = -1;
1345 }
1346 else if (dtimeout * 1000.0 > INT_MAX) {
1347 PyErr_SetString(PyExc_OverflowError,
1348 "timeout is too large");
1349 return NULL;
1350 }
1351 else {
1352 timeout = (int)(dtimeout * 1000.0);
1353 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 if (maxevents == -1) {
1356 maxevents = FD_SETSIZE-1;
1357 }
1358 else if (maxevents < 1) {
1359 PyErr_Format(PyExc_ValueError,
1360 "maxevents must be greater than 0, got %d",
1361 maxevents);
1362 return NULL;
1363 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 evs = PyMem_New(struct epoll_event, maxevents);
1366 if (evs == NULL) {
1367 Py_DECREF(self);
1368 PyErr_NoMemory();
1369 return NULL;
1370 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 Py_BEGIN_ALLOW_THREADS
1373 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1374 Py_END_ALLOW_THREADS
1375 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001376 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 goto error;
1378 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 elist = PyList_New(nfds);
1381 if (elist == NULL) {
1382 goto error;
1383 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 for (i = 0; i < nfds; i++) {
1386 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1387 if (etuple == NULL) {
1388 Py_CLEAR(elist);
1389 goto error;
1390 }
1391 PyList_SET_ITEM(elist, i, etuple);
1392 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393
Christian Heimesf6cd9672008-03-26 13:45:42 +00001394 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 PyMem_Free(evs);
1396 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001397}
1398
1399PyDoc_STRVAR(pyepoll_poll_doc,
1400"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1401\n\
1402Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1403in seconds (as float). -1 makes poll wait indefinitely.\n\
1404Up to maxevents are returned to the caller.");
1405
1406static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 {"fromfd", (PyCFunction)pyepoll_fromfd,
1408 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1409 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1410 pyepoll_close_doc},
1411 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1412 pyepoll_fileno_doc},
1413 {"modify", (PyCFunction)pyepoll_modify,
1414 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1415 {"register", (PyCFunction)pyepoll_register,
1416 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1417 {"unregister", (PyCFunction)pyepoll_unregister,
1418 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1419 {"poll", (PyCFunction)pyepoll_poll,
1420 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1421 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422};
1423
1424static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 {"closed", (getter)pyepoll_get_closed, NULL,
1426 "True if the epoll handler is closed"},
1427 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428};
1429
1430PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001431"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001432\n\
1433Returns an epolling object\n\
1434\n\
1435sizehint must be a positive integer or -1 for the default size. The\n\
1436sizehint is used to optimize internal data structures. It doesn't limit\n\
1437the maximum number of monitored events.");
1438
1439static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 PyVarObject_HEAD_INIT(NULL, 0)
1441 "select.epoll", /* tp_name */
1442 sizeof(pyEpoll_Object), /* tp_basicsize */
1443 0, /* tp_itemsize */
1444 (destructor)pyepoll_dealloc, /* tp_dealloc */
1445 0, /* tp_print */
1446 0, /* tp_getattr */
1447 0, /* tp_setattr */
1448 0, /* tp_reserved */
1449 0, /* tp_repr */
1450 0, /* tp_as_number */
1451 0, /* tp_as_sequence */
1452 0, /* tp_as_mapping */
1453 0, /* tp_hash */
1454 0, /* tp_call */
1455 0, /* tp_str */
1456 PyObject_GenericGetAttr, /* tp_getattro */
1457 0, /* tp_setattro */
1458 0, /* tp_as_buffer */
1459 Py_TPFLAGS_DEFAULT, /* tp_flags */
1460 pyepoll_doc, /* tp_doc */
1461 0, /* tp_traverse */
1462 0, /* tp_clear */
1463 0, /* tp_richcompare */
1464 0, /* tp_weaklistoffset */
1465 0, /* tp_iter */
1466 0, /* tp_iternext */
1467 pyepoll_methods, /* tp_methods */
1468 0, /* tp_members */
1469 pyepoll_getsetlist, /* tp_getset */
1470 0, /* tp_base */
1471 0, /* tp_dict */
1472 0, /* tp_descr_get */
1473 0, /* tp_descr_set */
1474 0, /* tp_dictoffset */
1475 0, /* tp_init */
1476 0, /* tp_alloc */
1477 pyepoll_new, /* tp_new */
1478 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001479};
1480
1481#endif /* HAVE_EPOLL */
1482
1483#ifdef HAVE_KQUEUE
1484/* **************************************************************************
1485 * kqueue interface for BSD
1486 *
1487 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1488 * All rights reserved.
1489 *
1490 * Redistribution and use in source and binary forms, with or without
1491 * modification, are permitted provided that the following conditions
1492 * are met:
1493 * 1. Redistributions of source code must retain the above copyright
1494 * notice, this list of conditions and the following disclaimer.
1495 * 2. Redistributions in binary form must reproduce the above copyright
1496 * notice, this list of conditions and the following disclaimer in the
1497 * documentation and/or other materials provided with the distribution.
1498 *
1499 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1500 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1501 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1502 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1503 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1504 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1505 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1506 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1507 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1508 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1509 * SUCH DAMAGE.
1510 */
1511
1512#ifdef HAVE_SYS_EVENT_H
1513#include <sys/event.h>
1514#endif
1515
1516PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001517"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001518\n\
1519This object is the equivalent of the struct kevent for the C API.\n\
1520\n\
1521See the kqueue manpage for more detailed information about the meaning\n\
1522of the arguments.\n\
1523\n\
1524One minor note: while you might hope that udata could store a\n\
1525reference to a python object, it cannot, because it is impossible to\n\
1526keep a proper reference count of the object once it's passed into the\n\
1527kernel. Therefore, I have restricted it to only storing an integer. I\n\
1528recommend ignoring it and simply using the 'ident' field to key off\n\
1529of. You could also set up a dictionary on the python side to store a\n\
1530udata->object mapping.");
1531
1532typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 PyObject_HEAD
1534 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001535} kqueue_event_Object;
1536
1537static PyTypeObject kqueue_event_Type;
1538
1539#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1540
1541typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 PyObject_HEAD
1543 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001544} kqueue_queue_Object;
1545
1546static PyTypeObject kqueue_queue_Type;
1547
1548#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1549
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001550#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1551# error uintptr_t does not match void *!
1552#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1553# define T_UINTPTRT T_ULONGLONG
1554# define T_INTPTRT T_LONGLONG
1555# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1556# define UINTPTRT_FMT_UNIT "K"
1557# define INTPTRT_FMT_UNIT "L"
1558#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1559# define T_UINTPTRT T_ULONG
1560# define T_INTPTRT T_LONG
1561# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1562# define UINTPTRT_FMT_UNIT "k"
1563# define INTPTRT_FMT_UNIT "l"
1564#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1565# define T_UINTPTRT T_UINT
1566# define T_INTPTRT T_INT
1567# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1568# define UINTPTRT_FMT_UNIT "I"
1569# define INTPTRT_FMT_UNIT "i"
1570#else
1571# error uintptr_t does not match int, long, or long long!
1572#endif
1573
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001574/* Unfortunately, we can't store python objects in udata, because
1575 * kevents in the kernel can be removed without warning, which would
1576 * forever lose the refcount on the object stored with it.
1577 */
1578
1579#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1580static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1582 {"filter", T_SHORT, KQ_OFF(e.filter)},
1583 {"flags", T_USHORT, KQ_OFF(e.flags)},
1584 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1585 {"data", T_INTPTRT, KQ_OFF(e.data)},
1586 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1587 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001588};
1589#undef KQ_OFF
1590
1591static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001592
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001593kqueue_event_repr(kqueue_event_Object *s)
1594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 char buf[1024];
1596 PyOS_snprintf(
1597 buf, sizeof(buf),
1598 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1599 "data=0x%zd udata=%p>",
1600 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1601 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1602 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001603}
1604
1605static int
1606kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 PyObject *pfd;
1609 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1610 "data", "udata", NULL};
1611 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1616 &pfd, &(self->e.filter), &(self->e.flags),
1617 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1618 return -1;
1619 }
1620
1621 if (PyLong_Check(pfd)) {
1622 self->e.ident = PyLong_AsUintptr_t(pfd);
1623 }
1624 else {
1625 self->e.ident = PyObject_AsFileDescriptor(pfd);
1626 }
1627 if (PyErr_Occurred()) {
1628 return -1;
1629 }
1630 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001631}
1632
1633static PyObject *
1634kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001636{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 if (!kqueue_event_Check(o)) {
1640 if (op == Py_EQ || op == Py_NE) {
1641 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1642 Py_INCREF(res);
1643 return res;
1644 }
1645 PyErr_Format(PyExc_TypeError,
1646 "can't compare %.200s to %.200s",
1647 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1648 return NULL;
1649 }
1650 if (((result = s->e.ident - o->e.ident) == 0) &&
1651 ((result = s->e.filter - o->e.filter) == 0) &&
1652 ((result = s->e.flags - o->e.flags) == 0) &&
1653 ((result = s->e.fflags - o->e.fflags) == 0) &&
1654 ((result = s->e.data - o->e.data) == 0) &&
1655 ((result = s->e.udata - o->e.udata) == 0)
1656 ) {
1657 result = 0;
1658 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 switch (op) {
1661 case Py_EQ:
1662 result = (result == 0);
1663 break;
1664 case Py_NE:
1665 result = (result != 0);
1666 break;
1667 case Py_LE:
1668 result = (result <= 0);
1669 break;
1670 case Py_GE:
1671 result = (result >= 0);
1672 break;
1673 case Py_LT:
1674 result = (result < 0);
1675 break;
1676 case Py_GT:
1677 result = (result > 0);
1678 break;
1679 }
1680 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001681}
1682
1683static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 PyVarObject_HEAD_INIT(NULL, 0)
1685 "select.kevent", /* tp_name */
1686 sizeof(kqueue_event_Object), /* tp_basicsize */
1687 0, /* tp_itemsize */
1688 0, /* tp_dealloc */
1689 0, /* tp_print */
1690 0, /* tp_getattr */
1691 0, /* tp_setattr */
1692 0, /* tp_reserved */
1693 (reprfunc)kqueue_event_repr, /* tp_repr */
1694 0, /* tp_as_number */
1695 0, /* tp_as_sequence */
1696 0, /* tp_as_mapping */
1697 0, /* tp_hash */
1698 0, /* tp_call */
1699 0, /* tp_str */
1700 0, /* tp_getattro */
1701 0, /* tp_setattro */
1702 0, /* tp_as_buffer */
1703 Py_TPFLAGS_DEFAULT, /* tp_flags */
1704 kqueue_event_doc, /* tp_doc */
1705 0, /* tp_traverse */
1706 0, /* tp_clear */
1707 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1708 0, /* tp_weaklistoffset */
1709 0, /* tp_iter */
1710 0, /* tp_iternext */
1711 0, /* tp_methods */
1712 kqueue_event_members, /* tp_members */
1713 0, /* tp_getset */
1714 0, /* tp_base */
1715 0, /* tp_dict */
1716 0, /* tp_descr_get */
1717 0, /* tp_descr_set */
1718 0, /* tp_dictoffset */
1719 (initproc)kqueue_event_init, /* tp_init */
1720 0, /* tp_alloc */
1721 0, /* tp_new */
1722 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001723};
1724
1725static PyObject *
1726kqueue_queue_err_closed(void)
1727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1729 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001730}
1731
1732static int
1733kqueue_queue_internal_close(kqueue_queue_Object *self)
1734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 int save_errno = 0;
1736 if (self->kqfd >= 0) {
1737 int kqfd = self->kqfd;
1738 self->kqfd = -1;
1739 Py_BEGIN_ALLOW_THREADS
1740 if (close(kqfd) < 0)
1741 save_errno = errno;
1742 Py_END_ALLOW_THREADS
1743 }
1744 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001745}
1746
1747static PyObject *
1748newKqueue_Object(PyTypeObject *type, SOCKET fd)
1749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 kqueue_queue_Object *self;
1751 assert(type != NULL && type->tp_alloc != NULL);
1752 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1753 if (self == NULL) {
1754 return NULL;
1755 }
1756
1757 if (fd == -1) {
1758 Py_BEGIN_ALLOW_THREADS
1759 self->kqfd = kqueue();
1760 Py_END_ALLOW_THREADS
1761 }
1762 else {
1763 self->kqfd = fd;
1764 }
1765 if (self->kqfd < 0) {
1766 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001767 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 return NULL;
1769 }
1770 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001771}
1772
1773static PyObject *
1774kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1775{
1776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 if ((args != NULL && PyObject_Size(args)) ||
1778 (kwds != NULL && PyObject_Size(kwds))) {
1779 PyErr_SetString(PyExc_ValueError,
1780 "select.kqueue doesn't accept arguments");
1781 return NULL;
1782 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001785}
1786
1787static void
1788kqueue_queue_dealloc(kqueue_queue_Object *self)
1789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 kqueue_queue_internal_close(self);
1791 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001792}
1793
1794static PyObject*
1795kqueue_queue_close(kqueue_queue_Object *self)
1796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 errno = kqueue_queue_internal_close(self);
1798 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001799 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 return NULL;
1801 }
1802 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001803}
1804
1805PyDoc_STRVAR(kqueue_queue_close_doc,
1806"close() -> None\n\
1807\n\
1808Close the kqueue control file descriptor. Further operations on the kqueue\n\
1809object will raise an exception.");
1810
1811static PyObject*
1812kqueue_queue_get_closed(kqueue_queue_Object *self)
1813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 if (self->kqfd < 0)
1815 Py_RETURN_TRUE;
1816 else
1817 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001818}
1819
1820static PyObject*
1821kqueue_queue_fileno(kqueue_queue_Object *self)
1822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 if (self->kqfd < 0)
1824 return kqueue_queue_err_closed();
1825 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001826}
1827
1828PyDoc_STRVAR(kqueue_queue_fileno_doc,
1829"fileno() -> int\n\
1830\n\
1831Return the kqueue control file descriptor.");
1832
1833static PyObject*
1834kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1839 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001842}
1843
1844PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1845"fromfd(fd) -> kqueue\n\
1846\n\
1847Create a kqueue object from a given control fd.");
1848
1849static PyObject *
1850kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 int nevents = 0;
1853 int gotevents = 0;
1854 int nchanges = 0;
1855 int i = 0;
1856 PyObject *otimeout = NULL;
1857 PyObject *ch = NULL;
1858 PyObject *it = NULL, *ei = NULL;
1859 PyObject *result = NULL;
1860 struct kevent *evl = NULL;
1861 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001862 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (self->kqfd < 0)
1866 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1869 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 if (nevents < 0) {
1872 PyErr_Format(PyExc_ValueError,
1873 "Length of eventlist must be 0 or positive, got %d",
1874 nevents);
1875 return NULL;
1876 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 if (otimeout == Py_None || otimeout == NULL) {
1879 ptimeoutspec = NULL;
1880 }
1881 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001882 if (_PyTime_ObjectToTimespec(otimeout,
1883 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1884 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001885
Victor Stinner5d272cc2012-03-13 13:35:55 +01001886 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 PyErr_SetString(PyExc_ValueError,
1888 "timeout must be positive or None");
1889 return NULL;
1890 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001891 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 }
1893 else {
1894 PyErr_Format(PyExc_TypeError,
1895 "timeout argument must be an number "
1896 "or None, got %.200s",
1897 Py_TYPE(otimeout)->tp_name);
1898 return NULL;
1899 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (ch != NULL && ch != Py_None) {
1902 it = PyObject_GetIter(ch);
1903 if (it == NULL) {
1904 PyErr_SetString(PyExc_TypeError,
1905 "changelist is not iterable");
1906 return NULL;
1907 }
1908 nchanges = PyObject_Size(ch);
1909 if (nchanges < 0) {
1910 goto error;
1911 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 chl = PyMem_New(struct kevent, nchanges);
1914 if (chl == NULL) {
1915 PyErr_NoMemory();
1916 goto error;
1917 }
1918 i = 0;
1919 while ((ei = PyIter_Next(it)) != NULL) {
1920 if (!kqueue_event_Check(ei)) {
1921 Py_DECREF(ei);
1922 PyErr_SetString(PyExc_TypeError,
1923 "changelist must be an iterable of "
1924 "select.kevent objects");
1925 goto error;
1926 } else {
1927 chl[i++] = ((kqueue_event_Object *)ei)->e;
1928 }
1929 Py_DECREF(ei);
1930 }
1931 }
1932 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 /* event list */
1935 if (nevents) {
1936 evl = PyMem_New(struct kevent, nevents);
1937 if (evl == NULL) {
1938 PyErr_NoMemory();
1939 goto error;
1940 }
1941 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 Py_BEGIN_ALLOW_THREADS
1944 gotevents = kevent(self->kqfd, chl, nchanges,
1945 evl, nevents, ptimeoutspec);
1946 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 if (gotevents == -1) {
1949 PyErr_SetFromErrno(PyExc_OSError);
1950 goto error;
1951 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 result = PyList_New(gotevents);
1954 if (result == NULL) {
1955 goto error;
1956 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 for (i = 0; i < gotevents; i++) {
1959 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1962 if (ch == NULL) {
1963 goto error;
1964 }
1965 ch->e = evl[i];
1966 PyList_SET_ITEM(result, i, (PyObject *)ch);
1967 }
1968 PyMem_Free(chl);
1969 PyMem_Free(evl);
1970 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001971
1972 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 PyMem_Free(chl);
1974 PyMem_Free(evl);
1975 Py_XDECREF(result);
1976 Py_XDECREF(it);
1977 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001978}
1979
1980PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001981"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001982\n\
1983Calls the kernel kevent function.\n\
1984- changelist must be a list of kevent objects describing the changes\n\
1985 to be made to the kernel's watch list or None.\n\
1986- max_events lets you specify the maximum number of events that the\n\
1987 kernel will return.\n\
1988- timeout is the maximum time to wait in seconds, or else None,\n\
1989 to wait forever. timeout accepts floats for smaller timeouts, too.");
1990
1991
1992static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1994 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1995 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1996 kqueue_queue_close_doc},
1997 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1998 kqueue_queue_fileno_doc},
1999 {"control", (PyCFunction)kqueue_queue_control,
2000 METH_VARARGS , kqueue_queue_control_doc},
2001 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002002};
2003
2004static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 {"closed", (getter)kqueue_queue_get_closed, NULL,
2006 "True if the kqueue handler is closed"},
2007 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002008};
2009
2010PyDoc_STRVAR(kqueue_queue_doc,
2011"Kqueue syscall wrapper.\n\
2012\n\
2013For example, to start watching a socket for input:\n\
2014>>> kq = kqueue()\n\
2015>>> sock = socket()\n\
2016>>> sock.connect((host, port))\n\
2017>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2018\n\
2019To wait one second for it to become writeable:\n\
2020>>> kq.control(None, 1, 1000)\n\
2021\n\
2022To stop listening:\n\
2023>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2024
2025static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 PyVarObject_HEAD_INIT(NULL, 0)
2027 "select.kqueue", /* tp_name */
2028 sizeof(kqueue_queue_Object), /* tp_basicsize */
2029 0, /* tp_itemsize */
2030 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2031 0, /* tp_print */
2032 0, /* tp_getattr */
2033 0, /* tp_setattr */
2034 0, /* tp_reserved */
2035 0, /* tp_repr */
2036 0, /* tp_as_number */
2037 0, /* tp_as_sequence */
2038 0, /* tp_as_mapping */
2039 0, /* tp_hash */
2040 0, /* tp_call */
2041 0, /* tp_str */
2042 0, /* tp_getattro */
2043 0, /* tp_setattro */
2044 0, /* tp_as_buffer */
2045 Py_TPFLAGS_DEFAULT, /* tp_flags */
2046 kqueue_queue_doc, /* tp_doc */
2047 0, /* tp_traverse */
2048 0, /* tp_clear */
2049 0, /* tp_richcompare */
2050 0, /* tp_weaklistoffset */
2051 0, /* tp_iter */
2052 0, /* tp_iternext */
2053 kqueue_queue_methods, /* tp_methods */
2054 0, /* tp_members */
2055 kqueue_queue_getsetlist, /* tp_getset */
2056 0, /* tp_base */
2057 0, /* tp_dict */
2058 0, /* tp_descr_get */
2059 0, /* tp_descr_set */
2060 0, /* tp_dictoffset */
2061 0, /* tp_init */
2062 0, /* tp_alloc */
2063 kqueue_queue_new, /* tp_new */
2064 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002065};
2066
2067#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002068
2069
2070
2071
2072
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002073/* ************************************************************************ */
2074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002076"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2077\n\
2078Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002079The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002080rlist -- wait until ready for reading\n\
2081wlist -- wait until ready for writing\n\
2082xlist -- wait for an ``exceptional condition''\n\
2083If only one kind of condition is required, pass [] for the other lists.\n\
2084A file descriptor is either a socket or file object, or a small integer\n\
2085gotten from a fileno() method call on one of those.\n\
2086\n\
2087The optional 4th argument specifies a timeout in seconds; it may be\n\
2088a floating point number to specify fractions of seconds. If it is absent\n\
2089or None, the call will never time out.\n\
2090\n\
2091The return value is a tuple of three lists corresponding to the first three\n\
2092arguments; each contains the subset of the corresponding file descriptors\n\
2093that are ready.\n\
2094\n\
2095*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002096On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002097descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002098
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002099static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002101#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002103#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002104#ifdef HAVE_SYS_DEVPOLL_H
2105 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2106#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002108};
2109
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002110PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002111"This module supports asynchronous I/O on multiple file descriptors.\n\
2112\n\
2113*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002114On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002115
Martin v. Löwis1a214512008-06-11 05:26:20 +00002116
2117static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 PyModuleDef_HEAD_INIT,
2119 "select",
2120 module_doc,
2121 -1,
2122 select_methods,
2123 NULL,
2124 NULL,
2125 NULL,
2126 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002127};
2128
Jesus Cead8b9ae62011-11-14 19:07:41 +01002129
2130
2131
Mark Hammond62b1ab12002-07-23 06:31:15 +00002132PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002133PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 PyObject *m;
2136 m = PyModule_Create(&selectmodule);
2137 if (m == NULL)
2138 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002139
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002140 Py_INCREF(PyExc_OSError);
2141 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002142
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002143#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002144#ifdef HAVE_BROKEN_PIPE_BUF
2145#undef PIPE_BUF
2146#define PIPE_BUF 512
2147#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002149#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002150
Charles-François Natali986a56c2013-01-19 12:19:10 +01002151#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002152#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 if (select_have_broken_poll()) {
2154 if (PyObject_DelAttrString(m, "poll") == -1) {
2155 PyErr_Clear();
2156 }
2157 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002158#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002160#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 if (PyType_Ready(&poll_Type) < 0)
2162 return NULL;
2163 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2164 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2165 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2166 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2167 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2168 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002169
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002170#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002172#endif
2173#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002175#endif
2176#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002178#endif
2179#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002181#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002182#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002184#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002186#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002187
Jesus Cead8b9ae62011-11-14 19:07:41 +01002188#ifdef HAVE_SYS_DEVPOLL_H
2189 if (PyType_Ready(&devpoll_Type) < 0)
2190 return NULL;
2191#endif
2192
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002193#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2195 if (PyType_Ready(&pyEpoll_Type) < 0)
2196 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 Py_INCREF(&pyEpoll_Type);
2199 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002201 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2202 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2203 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2204 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2205 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2206 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002207#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 /* Kernel 2.6.2+ */
2209 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002210#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2212 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2213 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2214 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2215 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2216 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002217
Benjamin Peterson95c16622011-12-27 15:36:32 -06002218#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002219 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002220#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002221#endif /* HAVE_EPOLL */
2222
2223#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 kqueue_event_Type.tp_new = PyType_GenericNew;
2225 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2226 if(PyType_Ready(&kqueue_event_Type) < 0)
2227 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 Py_INCREF(&kqueue_event_Type);
2230 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2233 if(PyType_Ready(&kqueue_queue_Type) < 0)
2234 return NULL;
2235 Py_INCREF(&kqueue_queue_Type);
2236 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2237
2238 /* event filters */
2239 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2240 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2241 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2242 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2243 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2248 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 /* event flags */
2251 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2252 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2253 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2254 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2255 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2256 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2259 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2262 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 /* READ WRITE filter flag */
2265 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 /* VNODE filter flags */
2268 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2269 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2272 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2273 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2274 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 /* PROC filter flags */
2277 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2278 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2279 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2280 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2281 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2284 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2285 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2286
2287 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002288#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2290 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2291 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002292#endif
2293
2294#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002296}