blob: 2ca2d41a15654a78d1647a92ca6691048eca1710 [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
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001574/*
1575 * kevent is not standard and its members vary across BSDs.
1576 */
1577#if !defined(__OpenBSD__)
1578# define IDENT_TYPE T_UINTPTRT
1579# define IDENT_CAST Py_intptr_t
1580# define DATA_TYPE T_INTPTRT
1581# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1582# define IDENT_AsType PyLong_AsUintptr_t
1583#else
1584# define IDENT_TYPE T_UINT
1585# define IDENT_CAST int
1586# define DATA_TYPE T_INT
1587# define DATA_FMT_UNIT "i"
1588# define IDENT_AsType PyLong_AsUnsignedLong
1589#endif
1590
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001591/* Unfortunately, we can't store python objects in udata, because
1592 * kevents in the kernel can be removed without warning, which would
1593 * forever lose the refcount on the object stored with it.
1594 */
1595
1596#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1597static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001598 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 {"filter", T_SHORT, KQ_OFF(e.filter)},
1600 {"flags", T_USHORT, KQ_OFF(e.flags)},
1601 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001602 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1604 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605};
1606#undef KQ_OFF
1607
1608static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001609
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001610kqueue_event_repr(kqueue_event_Object *s)
1611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 char buf[1024];
1613 PyOS_snprintf(
1614 buf, sizeof(buf),
1615 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1616 "data=0x%zd udata=%p>",
1617 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1618 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1619 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001620}
1621
1622static int
1623kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 PyObject *pfd;
1626 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1627 "data", "udata", NULL};
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001628 static char *fmt = "O|hhi" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1633 &pfd, &(self->e.filter), &(self->e.flags),
1634 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1635 return -1;
1636 }
1637
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001638 if (PyLong_Check(pfd)
1639#if IDENT_TYPE == T_UINT
1640 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1641#endif
1642 ) {
1643 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 }
1645 else {
1646 self->e.ident = PyObject_AsFileDescriptor(pfd);
1647 }
1648 if (PyErr_Occurred()) {
1649 return -1;
1650 }
1651 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652}
1653
1654static PyObject *
1655kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (!kqueue_event_Check(o)) {
1661 if (op == Py_EQ || op == Py_NE) {
1662 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1663 Py_INCREF(res);
1664 return res;
1665 }
1666 PyErr_Format(PyExc_TypeError,
1667 "can't compare %.200s to %.200s",
1668 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1669 return NULL;
1670 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001671 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 ((result = s->e.filter - o->e.filter) == 0) &&
1673 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001674 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 ((result = s->e.data - o->e.data) == 0) &&
1676 ((result = s->e.udata - o->e.udata) == 0)
1677 ) {
1678 result = 0;
1679 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 switch (op) {
1682 case Py_EQ:
1683 result = (result == 0);
1684 break;
1685 case Py_NE:
1686 result = (result != 0);
1687 break;
1688 case Py_LE:
1689 result = (result <= 0);
1690 break;
1691 case Py_GE:
1692 result = (result >= 0);
1693 break;
1694 case Py_LT:
1695 result = (result < 0);
1696 break;
1697 case Py_GT:
1698 result = (result > 0);
1699 break;
1700 }
1701 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001702}
1703
1704static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 PyVarObject_HEAD_INIT(NULL, 0)
1706 "select.kevent", /* tp_name */
1707 sizeof(kqueue_event_Object), /* tp_basicsize */
1708 0, /* tp_itemsize */
1709 0, /* tp_dealloc */
1710 0, /* tp_print */
1711 0, /* tp_getattr */
1712 0, /* tp_setattr */
1713 0, /* tp_reserved */
1714 (reprfunc)kqueue_event_repr, /* tp_repr */
1715 0, /* tp_as_number */
1716 0, /* tp_as_sequence */
1717 0, /* tp_as_mapping */
1718 0, /* tp_hash */
1719 0, /* tp_call */
1720 0, /* tp_str */
1721 0, /* tp_getattro */
1722 0, /* tp_setattro */
1723 0, /* tp_as_buffer */
1724 Py_TPFLAGS_DEFAULT, /* tp_flags */
1725 kqueue_event_doc, /* tp_doc */
1726 0, /* tp_traverse */
1727 0, /* tp_clear */
1728 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1729 0, /* tp_weaklistoffset */
1730 0, /* tp_iter */
1731 0, /* tp_iternext */
1732 0, /* tp_methods */
1733 kqueue_event_members, /* tp_members */
1734 0, /* tp_getset */
1735 0, /* tp_base */
1736 0, /* tp_dict */
1737 0, /* tp_descr_get */
1738 0, /* tp_descr_set */
1739 0, /* tp_dictoffset */
1740 (initproc)kqueue_event_init, /* tp_init */
1741 0, /* tp_alloc */
1742 0, /* tp_new */
1743 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001744};
1745
1746static PyObject *
1747kqueue_queue_err_closed(void)
1748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1750 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001751}
1752
1753static int
1754kqueue_queue_internal_close(kqueue_queue_Object *self)
1755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 int save_errno = 0;
1757 if (self->kqfd >= 0) {
1758 int kqfd = self->kqfd;
1759 self->kqfd = -1;
1760 Py_BEGIN_ALLOW_THREADS
1761 if (close(kqfd) < 0)
1762 save_errno = errno;
1763 Py_END_ALLOW_THREADS
1764 }
1765 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001766}
1767
1768static PyObject *
1769newKqueue_Object(PyTypeObject *type, SOCKET fd)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 kqueue_queue_Object *self;
1772 assert(type != NULL && type->tp_alloc != NULL);
1773 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1774 if (self == NULL) {
1775 return NULL;
1776 }
1777
1778 if (fd == -1) {
1779 Py_BEGIN_ALLOW_THREADS
1780 self->kqfd = kqueue();
1781 Py_END_ALLOW_THREADS
1782 }
1783 else {
1784 self->kqfd = fd;
1785 }
1786 if (self->kqfd < 0) {
1787 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001788 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 return NULL;
1790 }
1791 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001792}
1793
1794static PyObject *
1795kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1796{
1797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 if ((args != NULL && PyObject_Size(args)) ||
1799 (kwds != NULL && PyObject_Size(kwds))) {
1800 PyErr_SetString(PyExc_ValueError,
1801 "select.kqueue doesn't accept arguments");
1802 return NULL;
1803 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001806}
1807
1808static void
1809kqueue_queue_dealloc(kqueue_queue_Object *self)
1810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 kqueue_queue_internal_close(self);
1812 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001813}
1814
1815static PyObject*
1816kqueue_queue_close(kqueue_queue_Object *self)
1817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 errno = kqueue_queue_internal_close(self);
1819 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001820 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 return NULL;
1822 }
1823 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001824}
1825
1826PyDoc_STRVAR(kqueue_queue_close_doc,
1827"close() -> None\n\
1828\n\
1829Close the kqueue control file descriptor. Further operations on the kqueue\n\
1830object will raise an exception.");
1831
1832static PyObject*
1833kqueue_queue_get_closed(kqueue_queue_Object *self)
1834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 if (self->kqfd < 0)
1836 Py_RETURN_TRUE;
1837 else
1838 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001839}
1840
1841static PyObject*
1842kqueue_queue_fileno(kqueue_queue_Object *self)
1843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 if (self->kqfd < 0)
1845 return kqueue_queue_err_closed();
1846 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001847}
1848
1849PyDoc_STRVAR(kqueue_queue_fileno_doc,
1850"fileno() -> int\n\
1851\n\
1852Return the kqueue control file descriptor.");
1853
1854static PyObject*
1855kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1860 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863}
1864
1865PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1866"fromfd(fd) -> kqueue\n\
1867\n\
1868Create a kqueue object from a given control fd.");
1869
1870static PyObject *
1871kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 int nevents = 0;
1874 int gotevents = 0;
1875 int nchanges = 0;
1876 int i = 0;
1877 PyObject *otimeout = NULL;
1878 PyObject *ch = NULL;
1879 PyObject *it = NULL, *ei = NULL;
1880 PyObject *result = NULL;
1881 struct kevent *evl = NULL;
1882 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001883 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (self->kqfd < 0)
1887 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1890 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 if (nevents < 0) {
1893 PyErr_Format(PyExc_ValueError,
1894 "Length of eventlist must be 0 or positive, got %d",
1895 nevents);
1896 return NULL;
1897 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (otimeout == Py_None || otimeout == NULL) {
1900 ptimeoutspec = NULL;
1901 }
1902 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001903 if (_PyTime_ObjectToTimespec(otimeout,
1904 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1905 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001906
Victor Stinner5d272cc2012-03-13 13:35:55 +01001907 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 PyErr_SetString(PyExc_ValueError,
1909 "timeout must be positive or None");
1910 return NULL;
1911 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001912 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 }
1914 else {
1915 PyErr_Format(PyExc_TypeError,
1916 "timeout argument must be an number "
1917 "or None, got %.200s",
1918 Py_TYPE(otimeout)->tp_name);
1919 return NULL;
1920 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (ch != NULL && ch != Py_None) {
1923 it = PyObject_GetIter(ch);
1924 if (it == NULL) {
1925 PyErr_SetString(PyExc_TypeError,
1926 "changelist is not iterable");
1927 return NULL;
1928 }
1929 nchanges = PyObject_Size(ch);
1930 if (nchanges < 0) {
1931 goto error;
1932 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 chl = PyMem_New(struct kevent, nchanges);
1935 if (chl == NULL) {
1936 PyErr_NoMemory();
1937 goto error;
1938 }
1939 i = 0;
1940 while ((ei = PyIter_Next(it)) != NULL) {
1941 if (!kqueue_event_Check(ei)) {
1942 Py_DECREF(ei);
1943 PyErr_SetString(PyExc_TypeError,
1944 "changelist must be an iterable of "
1945 "select.kevent objects");
1946 goto error;
1947 } else {
1948 chl[i++] = ((kqueue_event_Object *)ei)->e;
1949 }
1950 Py_DECREF(ei);
1951 }
1952 }
1953 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 /* event list */
1956 if (nevents) {
1957 evl = PyMem_New(struct kevent, nevents);
1958 if (evl == NULL) {
1959 PyErr_NoMemory();
1960 goto error;
1961 }
1962 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 Py_BEGIN_ALLOW_THREADS
1965 gotevents = kevent(self->kqfd, chl, nchanges,
1966 evl, nevents, ptimeoutspec);
1967 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 if (gotevents == -1) {
1970 PyErr_SetFromErrno(PyExc_OSError);
1971 goto error;
1972 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 result = PyList_New(gotevents);
1975 if (result == NULL) {
1976 goto error;
1977 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 for (i = 0; i < gotevents; i++) {
1980 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1983 if (ch == NULL) {
1984 goto error;
1985 }
1986 ch->e = evl[i];
1987 PyList_SET_ITEM(result, i, (PyObject *)ch);
1988 }
1989 PyMem_Free(chl);
1990 PyMem_Free(evl);
1991 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001992
1993 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 PyMem_Free(chl);
1995 PyMem_Free(evl);
1996 Py_XDECREF(result);
1997 Py_XDECREF(it);
1998 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001999}
2000
2001PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002002"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003\n\
2004Calls the kernel kevent function.\n\
2005- changelist must be a list of kevent objects describing the changes\n\
2006 to be made to the kernel's watch list or None.\n\
2007- max_events lets you specify the maximum number of events that the\n\
2008 kernel will return.\n\
2009- timeout is the maximum time to wait in seconds, or else None,\n\
2010 to wait forever. timeout accepts floats for smaller timeouts, too.");
2011
2012
2013static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2015 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2016 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2017 kqueue_queue_close_doc},
2018 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2019 kqueue_queue_fileno_doc},
2020 {"control", (PyCFunction)kqueue_queue_control,
2021 METH_VARARGS , kqueue_queue_control_doc},
2022 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002023};
2024
2025static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 {"closed", (getter)kqueue_queue_get_closed, NULL,
2027 "True if the kqueue handler is closed"},
2028 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002029};
2030
2031PyDoc_STRVAR(kqueue_queue_doc,
2032"Kqueue syscall wrapper.\n\
2033\n\
2034For example, to start watching a socket for input:\n\
2035>>> kq = kqueue()\n\
2036>>> sock = socket()\n\
2037>>> sock.connect((host, port))\n\
2038>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2039\n\
2040To wait one second for it to become writeable:\n\
2041>>> kq.control(None, 1, 1000)\n\
2042\n\
2043To stop listening:\n\
2044>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2045
2046static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 PyVarObject_HEAD_INIT(NULL, 0)
2048 "select.kqueue", /* tp_name */
2049 sizeof(kqueue_queue_Object), /* tp_basicsize */
2050 0, /* tp_itemsize */
2051 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2052 0, /* tp_print */
2053 0, /* tp_getattr */
2054 0, /* tp_setattr */
2055 0, /* tp_reserved */
2056 0, /* tp_repr */
2057 0, /* tp_as_number */
2058 0, /* tp_as_sequence */
2059 0, /* tp_as_mapping */
2060 0, /* tp_hash */
2061 0, /* tp_call */
2062 0, /* tp_str */
2063 0, /* tp_getattro */
2064 0, /* tp_setattro */
2065 0, /* tp_as_buffer */
2066 Py_TPFLAGS_DEFAULT, /* tp_flags */
2067 kqueue_queue_doc, /* tp_doc */
2068 0, /* tp_traverse */
2069 0, /* tp_clear */
2070 0, /* tp_richcompare */
2071 0, /* tp_weaklistoffset */
2072 0, /* tp_iter */
2073 0, /* tp_iternext */
2074 kqueue_queue_methods, /* tp_methods */
2075 0, /* tp_members */
2076 kqueue_queue_getsetlist, /* tp_getset */
2077 0, /* tp_base */
2078 0, /* tp_dict */
2079 0, /* tp_descr_get */
2080 0, /* tp_descr_set */
2081 0, /* tp_dictoffset */
2082 0, /* tp_init */
2083 0, /* tp_alloc */
2084 kqueue_queue_new, /* tp_new */
2085 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002086};
2087
2088#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002089
2090
2091
2092
2093
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002094/* ************************************************************************ */
2095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002096PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002097"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2098\n\
2099Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002100The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002101rlist -- wait until ready for reading\n\
2102wlist -- wait until ready for writing\n\
2103xlist -- wait for an ``exceptional condition''\n\
2104If only one kind of condition is required, pass [] for the other lists.\n\
2105A file descriptor is either a socket or file object, or a small integer\n\
2106gotten from a fileno() method call on one of those.\n\
2107\n\
2108The optional 4th argument specifies a timeout in seconds; it may be\n\
2109a floating point number to specify fractions of seconds. If it is absent\n\
2110or None, the call will never time out.\n\
2111\n\
2112The return value is a tuple of three lists corresponding to the first three\n\
2113arguments; each contains the subset of the corresponding file descriptors\n\
2114that are ready.\n\
2115\n\
2116*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002117On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002118descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002119
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002120static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002122#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002124#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002125#ifdef HAVE_SYS_DEVPOLL_H
2126 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2127#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002129};
2130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002132"This module supports asynchronous I/O on multiple file descriptors.\n\
2133\n\
2134*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002135On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002136
Martin v. Löwis1a214512008-06-11 05:26:20 +00002137
2138static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 PyModuleDef_HEAD_INIT,
2140 "select",
2141 module_doc,
2142 -1,
2143 select_methods,
2144 NULL,
2145 NULL,
2146 NULL,
2147 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002148};
2149
Jesus Cead8b9ae62011-11-14 19:07:41 +01002150
2151
2152
Mark Hammond62b1ab12002-07-23 06:31:15 +00002153PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002154PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 PyObject *m;
2157 m = PyModule_Create(&selectmodule);
2158 if (m == NULL)
2159 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002160
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002161 Py_INCREF(PyExc_OSError);
2162 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002163
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002164#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002165#ifdef HAVE_BROKEN_PIPE_BUF
2166#undef PIPE_BUF
2167#define PIPE_BUF 512
2168#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002170#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002171
Charles-François Natali986a56c2013-01-19 12:19:10 +01002172#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002173#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 if (select_have_broken_poll()) {
2175 if (PyObject_DelAttrString(m, "poll") == -1) {
2176 PyErr_Clear();
2177 }
2178 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002179#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002181#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 if (PyType_Ready(&poll_Type) < 0)
2183 return NULL;
2184 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2185 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2186 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2187 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2188 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2189 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002190
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002191#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002193#endif
2194#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002196#endif
2197#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002199#endif
2200#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002201 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002202#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002203#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002205#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002207#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002208
Jesus Cead8b9ae62011-11-14 19:07:41 +01002209#ifdef HAVE_SYS_DEVPOLL_H
2210 if (PyType_Ready(&devpoll_Type) < 0)
2211 return NULL;
2212#endif
2213
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002214#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2216 if (PyType_Ready(&pyEpoll_Type) < 0)
2217 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 Py_INCREF(&pyEpoll_Type);
2220 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2223 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2224 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2225 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2226 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2227 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 /* Kernel 2.6.2+ */
2230 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2233 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2234 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2235 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2236 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2237 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002238
Benjamin Peterson95c16622011-12-27 15:36:32 -06002239#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002240 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002241#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242#endif /* HAVE_EPOLL */
2243
2244#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 kqueue_event_Type.tp_new = PyType_GenericNew;
2246 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2247 if(PyType_Ready(&kqueue_event_Type) < 0)
2248 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 Py_INCREF(&kqueue_event_Type);
2251 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2254 if(PyType_Ready(&kqueue_queue_Type) < 0)
2255 return NULL;
2256 Py_INCREF(&kqueue_queue_Type);
2257 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2258
2259 /* event filters */
2260 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2261 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2262 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2263 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2264 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002265#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002267#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2269 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 /* event flags */
2272 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2273 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2274 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2275 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2276 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2277 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2280 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2283 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 /* READ WRITE filter flag */
2286 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 /* VNODE filter flags */
2289 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2290 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2291 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2292 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2293 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2294 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2295 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 /* PROC filter flags */
2298 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2299 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2300 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2301 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2302 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2305 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2306 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2307
2308 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002309#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2311 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2312 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002313#endif
2314
2315#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002317}