blob: 252dee2360621630fc861337e11627cd5bffcdd0 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Jesus Cead8b9ae62011-11-14 19:07:41 +010010#ifdef HAVE_SYS_DEVPOLL_H
11#include <sys/resource.h>
12#include <sys/devpoll.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018#ifdef __APPLE__
19 /* Perform runtime testing for a broken poll on OSX to make it easier
20 * to use the same binary on multiple releases of the OS.
21 */
22#undef HAVE_BROKEN_POLL
23#endif
24
Tim Petersd92dfe02000-12-12 01:18:41 +000025/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
26 64 is too small (too many people have bumped into that limit).
27 Here we boost it.
28 Users who want even more than the boosted limit should #define
29 FD_SETSIZE higher before this; e.g., via compiler /D switch.
30*/
31#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
32#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000034
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000035#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000036#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000037#elif defined(HAVE_SYS_POLL_H)
38#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000039#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000040
Guido van Rossum37273171996-12-09 18:47:43 +000041#ifdef __sgi
42/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000043extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000044#endif
45
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000048#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049
Guido van Rossum6f489d91996-06-28 20:15:15 +000050#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000051# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000055# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <socket.h>
57# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000058#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000059
Barry Warsawc1cb3601996-12-12 22:16:21 +000060/* list of Python objects and their file descriptor */
61typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 PyObject *obj; /* owned reference */
63 SOCKET fd;
64 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000065} pylist;
66
Barry Warsawc1cb3601996-12-12 22:16:21 +000067static void
Tim Peters4b046c22001-08-16 21:59:46 +000068reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 int i;
71 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
72 Py_XDECREF(fd2obj[i].obj);
73 fd2obj[i].obj = NULL;
74 }
75 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000076}
77
78
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000079/* returns -1 and sets the Python exception if an error occurred, otherwise
80 returns a number >= 0
81*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000082static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000083seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 int max = -1;
86 int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010087 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 PyObject* fast_seq = NULL;
89 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
92 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000094 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (!fast_seq)
96 return -1;
97
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010098 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 SOCKET v;
100
101 /* any intervening fileno() calls could decr this refcnt */
102 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200103 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 Py_INCREF(o);
106 v = PyObject_AsFileDescriptor( o );
107 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000108
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000109#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000111#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200112 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 PyErr_SetString(PyExc_ValueError,
114 "filedescriptor out of range in select()");
115 goto finally;
116 }
117 if (v > max)
118 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 /* add object and its file descriptor to the list */
123 if (index >= FD_SETSIZE) {
124 PyErr_SetString(PyExc_ValueError,
125 "too many file descriptors in select()");
126 goto finally;
127 }
128 fd2obj[index].obj = o;
129 fd2obj[index].fd = v;
130 fd2obj[index].sentinel = 0;
131 fd2obj[++index].sentinel = -1;
132 }
133 Py_DECREF(fast_seq);
134 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135
136 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 Py_XDECREF(o);
138 Py_DECREF(fast_seq);
139 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000140}
141
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000142/* returns NULL and sets the Python exception if an error occurred */
143static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 int i, j, count=0;
147 PyObject *list, *o;
148 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
151 if (FD_ISSET(fd2obj[j].fd, set))
152 count++;
153 }
154 list = PyList_New(count);
155 if (!list)
156 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 i = 0;
159 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
160 fd = fd2obj[j].fd;
161 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 o = fd2obj[j].obj;
163 fd2obj[j].obj = NULL;
164 /* transfer ownership */
165 if (PyList_SetItem(list, i, o) < 0)
166 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 i++;
169 }
170 }
171 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 Py_DECREF(list);
174 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000175}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000176
Barry Warsawb44740f2001-08-16 16:52:59 +0000177#undef SELECT_USES_HEAP
178#if FD_SETSIZE > 1024
179#define SELECT_USES_HEAP
180#endif /* FD_SETSIZE > 1024 */
181
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000182static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000183select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000184{
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 /* XXX: All this should probably be implemented as follows:
189 * - find the highest descriptor we're interested in
190 * - add one
191 * - that's the size
192 * See: Stevens, APitUE, $12.5.1
193 */
194 pylist rfd2obj[FD_SETSIZE + 1];
195 pylist wfd2obj[FD_SETSIZE + 1];
196 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000197#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 PyObject *ifdlist, *ofdlist, *efdlist;
199 PyObject *ret = NULL;
200 PyObject *tout = Py_None;
201 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 int imax, omax, emax, max;
204 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 /* convert arguments */
207 if (!PyArg_UnpackTuple(args, "select", 3, 4,
208 &ifdlist, &ofdlist, &efdlist, &tout))
209 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 if (tout == Py_None)
212 tvp = (struct timeval *)0;
213 else if (!PyNumber_Check(tout)) {
214 PyErr_SetString(PyExc_TypeError,
215 "timeout must be a float or None");
216 return NULL;
217 }
218 else {
Victor Stinnerb2a37732012-03-14 00:20:51 +0100219#ifdef MS_WINDOWS
220 time_t sec;
221 if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 return NULL;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100223 assert(sizeof(tv.tv_sec) == sizeof(long));
224#if SIZEOF_TIME_T > SIZEOF_LONG
225 if (sec > LONG_MAX) {
226 PyErr_SetString(PyExc_OverflowError,
227 "timeout is too large");
228 return NULL;
229 }
230#endif
231 tv.tv_sec = (long)sec;
232#else
Brett Cannon8798ad32012-04-07 14:59:29 -0400233 /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4
234 bytes as required), but no longer defined by a long. */
Benjamin Peterson6f3e5e42012-09-11 12:05:05 -0400235 long tv_usec;
Brett Cannon8798ad32012-04-07 14:59:29 -0400236 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1)
Victor Stinnerb2a37732012-03-14 00:20:51 +0100237 return NULL;
Brett Cannon8798ad32012-04-07 14:59:29 -0400238 tv.tv_usec = tv_usec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100239#endif
Victor Stinner5d272cc2012-03-13 13:35:55 +0100240 if (tv.tv_sec < 0) {
241 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 return NULL;
243 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 tvp = &tv;
245 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000246
Guido van Rossumed233a51992-06-23 09:07:03 +0000247
Barry Warsawb44740f2001-08-16 16:52:59 +0000248#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 /* Allocate memory for the lists */
250 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
251 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
254 if (rfd2obj) PyMem_DEL(rfd2obj);
255 if (wfd2obj) PyMem_DEL(wfd2obj);
256 if (efd2obj) PyMem_DEL(efd2obj);
257 return PyErr_NoMemory();
258 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000259#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 /* Convert sequences to fd_sets, and get maximum fd number
261 * propagates the Python exception set in seq2set()
262 */
263 rfd2obj[0].sentinel = -1;
264 wfd2obj[0].sentinel = -1;
265 efd2obj[0].sentinel = -1;
266 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
267 goto finally;
268 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
269 goto finally;
270 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
271 goto finally;
272 max = imax;
273 if (omax > max) max = omax;
274 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 Py_BEGIN_ALLOW_THREADS
277 n = select(max, &ifdset, &ofdset, &efdset, tvp);
278 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000279
Thomas Heller106f4c72002-09-24 16:51:00 +0000280#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200282 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000284#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200286 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000288#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 else {
290 /* any of these three calls can raise an exception. it's more
291 convenient to test for this after all three calls... but
292 is that acceptable?
293 */
294 ifdlist = set2list(&ifdset, rfd2obj);
295 ofdlist = set2list(&ofdset, wfd2obj);
296 efdlist = set2list(&efdset, efd2obj);
297 if (PyErr_Occurred())
298 ret = NULL;
299 else
300 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000301
Victor Stinnerbbf8ce52013-07-09 00:49:03 +0200302 Py_XDECREF(ifdlist);
303 Py_XDECREF(ofdlist);
304 Py_XDECREF(efdlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 }
306
Barry Warsawc1cb3601996-12-12 22:16:21 +0000307 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 reap_obj(rfd2obj);
309 reap_obj(wfd2obj);
310 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000311#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 PyMem_DEL(rfd2obj);
313 PyMem_DEL(wfd2obj);
314 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000315#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000317}
318
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000319#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000321 * poll() support
322 */
323
324typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 PyObject_HEAD
326 PyObject *dict;
327 int ufd_uptodate;
328 int ufd_len;
329 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000330} pollObject;
331
Jeremy Hylton938ace62002-07-17 16:30:39 +0000332static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335 contained within a pollObject. Return 1 on success, 0 on an error.
336*/
337
338static int
339update_ufd_array(pollObject *self)
340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 Py_ssize_t i, pos;
342 PyObject *key, *value;
343 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 self->ufd_len = PyDict_Size(self->dict);
346 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
347 if (self->ufds == NULL) {
348 self->ufds = old_ufds;
349 PyErr_NoMemory();
350 return 0;
351 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 i = pos = 0;
354 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200355 assert(i < self->ufd_len);
356 /* Never overflow */
357 self->ufds[i].fd = (int)PyLong_AsLong(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 self->ufds[i].events = (short)PyLong_AsLong(value);
359 i++;
360 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200361 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 self->ufd_uptodate = 1;
363 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000364}
365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000366PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367"register(fd [, eventmask] ) -> None\n\n\
368Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000369fd -- either an integer, or an object with a fileno() method returning an\n\
370 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000371events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000372
373static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 PyObject *o, *key, *value;
Serhiy Storchaka78980432013-01-15 01:12:17 +0200377 int fd;
378 short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000380
Serhiy Storchaka78980432013-01-15 01:12:17 +0200381 if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 return NULL;
383 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 fd = PyObject_AsFileDescriptor(o);
386 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 /* Add entry to the internal dictionary: the key is the
389 file descriptor, and the value is the event mask. */
390 key = PyLong_FromLong(fd);
391 if (key == NULL)
392 return NULL;
393 value = PyLong_FromLong(events);
394 if (value == NULL) {
395 Py_DECREF(key);
396 return NULL;
397 }
398 err = PyDict_SetItem(self->dict, key, value);
399 Py_DECREF(key);
400 Py_DECREF(value);
401 if (err < 0)
402 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 self->ufd_uptodate = 0;
405
406 Py_INCREF(Py_None);
407 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000408}
409
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000410PyDoc_STRVAR(poll_modify_doc,
411"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000412Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000413fd -- either an integer, or an object with a fileno() method returning an\n\
414 int.\n\
415events -- an optional bitmask describing the type of events to check for");
416
417static PyObject *
418poll_modify(pollObject *self, PyObject *args)
419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 PyObject *o, *key, *value;
421 int fd, events;
422 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
425 return NULL;
426 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 fd = PyObject_AsFileDescriptor(o);
429 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 /* Modify registered fd */
432 key = PyLong_FromLong(fd);
433 if (key == NULL)
434 return NULL;
435 if (PyDict_GetItem(self->dict, key) == NULL) {
436 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200437 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200438 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 return NULL;
440 }
441 value = PyLong_FromLong(events);
442 if (value == NULL) {
443 Py_DECREF(key);
444 return NULL;
445 }
446 err = PyDict_SetItem(self->dict, key, value);
447 Py_DECREF(key);
448 Py_DECREF(value);
449 if (err < 0)
450 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 self->ufd_uptodate = 0;
453
454 Py_INCREF(Py_None);
455 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000456}
457
458
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000459PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000460"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000461Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462
463static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 PyObject *key;
467 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 fd = PyObject_AsFileDescriptor( o );
470 if (fd == -1)
471 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 /* Check whether the fd is already in the array */
474 key = PyLong_FromLong(fd);
475 if (key == NULL)
476 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 if (PyDict_DelItem(self->dict, key) == -1) {
479 Py_DECREF(key);
480 /* This will simply raise the KeyError set by PyDict_DelItem
481 if the file descriptor isn't registered. */
482 return NULL;
483 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 Py_DECREF(key);
486 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 Py_INCREF(Py_None);
489 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000490}
491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000492PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
494Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000495any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496
497static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 PyObject *result_list = NULL, *tout = NULL;
501 int timeout = 0, poll_result, i, j;
502 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
505 return NULL;
506 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 /* Check values for timeout */
509 if (tout == NULL || tout == Py_None)
510 timeout = -1;
511 else if (!PyNumber_Check(tout)) {
512 PyErr_SetString(PyExc_TypeError,
513 "timeout must be an integer or None");
514 return NULL;
515 }
516 else {
517 tout = PyNumber_Long(tout);
518 if (!tout)
519 return NULL;
Serhiy Storchaka78980432013-01-15 01:12:17 +0200520 timeout = _PyLong_AsInt(tout);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 Py_DECREF(tout);
522 if (timeout == -1 && PyErr_Occurred())
523 return NULL;
524 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 /* Ensure the ufd array is up to date */
527 if (!self->ufd_uptodate)
528 if (update_ufd_array(self) == 0)
529 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 /* call poll() */
532 Py_BEGIN_ALLOW_THREADS
533 poll_result = poll(self->ufds, self->ufd_len, timeout);
534 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200537 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 return NULL;
539 }
540
541 /* build the result list */
542
543 result_list = PyList_New(poll_result);
544 if (!result_list)
545 return NULL;
546 else {
547 for (i = 0, j = 0; j < poll_result; j++) {
548 /* skip to the next fired descriptor */
549 while (!self->ufds[i].revents) {
550 i++;
551 }
552 /* if we hit a NULL return, set value to NULL
553 and break out of loop; code at end will
554 clean up result_list */
555 value = PyTuple_New(2);
556 if (value == NULL)
557 goto error;
558 num = PyLong_FromLong(self->ufds[i].fd);
559 if (num == NULL) {
560 Py_DECREF(value);
561 goto error;
562 }
563 PyTuple_SET_ITEM(value, 0, num);
564
565 /* The &0xffff is a workaround for AIX. 'revents'
566 is a 16-bit short, and IBM assigned POLLNVAL
567 to be 0x8000, so the conversion to int results
568 in a negative number. See SF bug #923315. */
569 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
570 if (num == NULL) {
571 Py_DECREF(value);
572 goto error;
573 }
574 PyTuple_SET_ITEM(value, 1, num);
575 if ((PyList_SetItem(result_list, j, value)) == -1) {
576 Py_DECREF(value);
577 goto error;
578 }
579 i++;
580 }
581 }
582 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583
584 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 Py_DECREF(result_list);
586 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000587}
588
589static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 {"register", (PyCFunction)poll_register,
591 METH_VARARGS, poll_register_doc},
592 {"modify", (PyCFunction)poll_modify,
593 METH_VARARGS, poll_modify_doc},
594 {"unregister", (PyCFunction)poll_unregister,
595 METH_O, poll_unregister_doc},
596 {"poll", (PyCFunction)poll_poll,
597 METH_VARARGS, poll_poll_doc},
598 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000599};
600
601static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000602newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 pollObject *self;
605 self = PyObject_New(pollObject, &poll_Type);
606 if (self == NULL)
607 return NULL;
608 /* ufd_uptodate is a Boolean, denoting whether the
609 array pointed to by ufds matches the contents of the dictionary. */
610 self->ufd_uptodate = 0;
611 self->ufds = NULL;
612 self->dict = PyDict_New();
613 if (self->dict == NULL) {
614 Py_DECREF(self);
615 return NULL;
616 }
617 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000618}
619
620static void
621poll_dealloc(pollObject *self)
622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 if (self->ufds != NULL)
624 PyMem_DEL(self->ufds);
625 Py_XDECREF(self->dict);
626 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000627}
628
Tim Peters0c322792002-07-17 16:49:03 +0000629static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 /* The ob_type field must be initialized in the module init function
631 * to be portable to Windows without using C++. */
632 PyVarObject_HEAD_INIT(NULL, 0)
633 "select.poll", /*tp_name*/
634 sizeof(pollObject), /*tp_basicsize*/
635 0, /*tp_itemsize*/
636 /* methods */
637 (destructor)poll_dealloc, /*tp_dealloc*/
638 0, /*tp_print*/
639 0, /*tp_getattr*/
640 0, /*tp_setattr*/
641 0, /*tp_reserved*/
642 0, /*tp_repr*/
643 0, /*tp_as_number*/
644 0, /*tp_as_sequence*/
645 0, /*tp_as_mapping*/
646 0, /*tp_hash*/
647 0, /*tp_call*/
648 0, /*tp_str*/
649 0, /*tp_getattro*/
650 0, /*tp_setattro*/
651 0, /*tp_as_buffer*/
652 Py_TPFLAGS_DEFAULT, /*tp_flags*/
653 0, /*tp_doc*/
654 0, /*tp_traverse*/
655 0, /*tp_clear*/
656 0, /*tp_richcompare*/
657 0, /*tp_weaklistoffset*/
658 0, /*tp_iter*/
659 0, /*tp_iternext*/
660 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000661};
662
Jesus Cead8b9ae62011-11-14 19:07:41 +0100663#ifdef HAVE_SYS_DEVPOLL_H
664typedef struct {
665 PyObject_HEAD
666 int fd_devpoll;
667 int max_n_fds;
668 int n_fds;
669 struct pollfd *fds;
670} devpollObject;
671
672static PyTypeObject devpoll_Type;
673
674static int devpoll_flush(devpollObject *self)
675{
676 int size, n;
677
678 if (!self->n_fds) return 0;
679
680 size = sizeof(struct pollfd)*self->n_fds;
681 self->n_fds = 0;
682
683 Py_BEGIN_ALLOW_THREADS
684 n = write(self->fd_devpoll, self->fds, size);
685 Py_END_ALLOW_THREADS
686
687 if (n == -1 ) {
688 PyErr_SetFromErrno(PyExc_IOError);
689 return -1;
690 }
691 if (n < size) {
692 /*
693 ** Data writed to /dev/poll is a binary data structure. It is not
694 ** clear what to do if a partial write occurred. For now, raise
695 ** an exception and see if we actually found this problem in
696 ** the wild.
697 ** See http://bugs.python.org/issue6397.
698 */
699 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
700 "Please, report at http://bugs.python.org/. "
701 "Data to report: Size tried: %d, actual size written: %d.",
702 size, n);
703 return -1;
704 }
705 return 0;
706}
707
708static PyObject *
709internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
710{
711 PyObject *o;
712 int fd, events = POLLIN | POLLPRI | POLLOUT;
713
714 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
715 return NULL;
716 }
717
718 fd = PyObject_AsFileDescriptor(o);
719 if (fd == -1) return NULL;
720
721 if (remove) {
722 self->fds[self->n_fds].fd = fd;
723 self->fds[self->n_fds].events = POLLREMOVE;
724
725 if (++self->n_fds == self->max_n_fds) {
726 if (devpoll_flush(self))
727 return NULL;
728 }
729 }
730
731 self->fds[self->n_fds].fd = fd;
732 self->fds[self->n_fds].events = events;
733
734 if (++self->n_fds == self->max_n_fds) {
735 if (devpoll_flush(self))
736 return NULL;
737 }
738
739 Py_RETURN_NONE;
740}
741
742PyDoc_STRVAR(devpoll_register_doc,
743"register(fd [, eventmask] ) -> None\n\n\
744Register a file descriptor with the polling object.\n\
745fd -- either an integer, or an object with a fileno() method returning an\n\
746 int.\n\
747events -- an optional bitmask describing the type of events to check for");
748
749static PyObject *
750devpoll_register(devpollObject *self, PyObject *args)
751{
752 return internal_devpoll_register(self, args, 0);
753}
754
755PyDoc_STRVAR(devpoll_modify_doc,
756"modify(fd[, eventmask]) -> None\n\n\
757Modify a possible already registered file descriptor.\n\
758fd -- either an integer, or an object with a fileno() method returning an\n\
759 int.\n\
760events -- an optional bitmask describing the type of events to check for");
761
762static PyObject *
763devpoll_modify(devpollObject *self, PyObject *args)
764{
765 return internal_devpoll_register(self, args, 1);
766}
767
768
769PyDoc_STRVAR(devpoll_unregister_doc,
770"unregister(fd) -> None\n\n\
771Remove a file descriptor being tracked by the polling object.");
772
773static PyObject *
774devpoll_unregister(devpollObject *self, PyObject *o)
775{
776 int fd;
777
778 fd = PyObject_AsFileDescriptor( o );
779 if (fd == -1)
780 return NULL;
781
782 self->fds[self->n_fds].fd = fd;
783 self->fds[self->n_fds].events = POLLREMOVE;
784
785 if (++self->n_fds == self->max_n_fds) {
786 if (devpoll_flush(self))
787 return NULL;
788 }
789
790 Py_RETURN_NONE;
791}
792
793PyDoc_STRVAR(devpoll_poll_doc,
794"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
795Polls the set of registered file descriptors, returning a list containing \n\
796any descriptors that have events or errors to report.");
797
798static PyObject *
799devpoll_poll(devpollObject *self, PyObject *args)
800{
801 struct dvpoll dvp;
802 PyObject *result_list = NULL, *tout = NULL;
803 int poll_result, i;
804 long timeout;
805 PyObject *value, *num1, *num2;
806
807 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
808 return NULL;
809 }
810
811 /* Check values for timeout */
812 if (tout == NULL || tout == Py_None)
813 timeout = -1;
814 else if (!PyNumber_Check(tout)) {
815 PyErr_SetString(PyExc_TypeError,
816 "timeout must be an integer or None");
817 return NULL;
818 }
819 else {
820 tout = PyNumber_Long(tout);
821 if (!tout)
822 return NULL;
823 timeout = PyLong_AsLong(tout);
824 Py_DECREF(tout);
825 if (timeout == -1 && PyErr_Occurred())
826 return NULL;
827 }
828
829 if ((timeout < -1) || (timeout > INT_MAX)) {
830 PyErr_SetString(PyExc_OverflowError,
831 "timeout is out of range");
832 return NULL;
833 }
834
835 if (devpoll_flush(self))
836 return NULL;
837
838 dvp.dp_fds = self->fds;
839 dvp.dp_nfds = self->max_n_fds;
840 dvp.dp_timeout = timeout;
841
842 /* call devpoll() */
843 Py_BEGIN_ALLOW_THREADS
844 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
845 Py_END_ALLOW_THREADS
846
847 if (poll_result < 0) {
848 PyErr_SetFromErrno(PyExc_IOError);
849 return NULL;
850 }
851
852 /* build the result list */
853
854 result_list = PyList_New(poll_result);
855 if (!result_list)
856 return NULL;
857 else {
858 for (i = 0; i < poll_result; i++) {
859 num1 = PyLong_FromLong(self->fds[i].fd);
860 num2 = PyLong_FromLong(self->fds[i].revents);
861 if ((num1 == NULL) || (num2 == NULL)) {
862 Py_XDECREF(num1);
863 Py_XDECREF(num2);
864 goto error;
865 }
866 value = PyTuple_Pack(2, num1, num2);
867 Py_DECREF(num1);
868 Py_DECREF(num2);
869 if (value == NULL)
870 goto error;
871 if ((PyList_SetItem(result_list, i, value)) == -1) {
872 Py_DECREF(value);
873 goto error;
874 }
875 }
876 }
877
878 return result_list;
879
880 error:
881 Py_DECREF(result_list);
882 return NULL;
883}
884
885static PyMethodDef devpoll_methods[] = {
886 {"register", (PyCFunction)devpoll_register,
887 METH_VARARGS, devpoll_register_doc},
888 {"modify", (PyCFunction)devpoll_modify,
889 METH_VARARGS, devpoll_modify_doc},
890 {"unregister", (PyCFunction)devpoll_unregister,
891 METH_O, devpoll_unregister_doc},
892 {"poll", (PyCFunction)devpoll_poll,
893 METH_VARARGS, devpoll_poll_doc},
894 {NULL, NULL} /* sentinel */
895};
896
897static devpollObject *
898newDevPollObject(void)
899{
900 devpollObject *self;
901 int fd_devpoll, limit_result;
902 struct pollfd *fds;
903 struct rlimit limit;
904
905 Py_BEGIN_ALLOW_THREADS
906 /*
907 ** If we try to process more that getrlimit()
908 ** fds, the kernel will give an error, so
909 ** we set the limit here. It is a dynamic
910 ** value, because we can change rlimit() anytime.
911 */
912 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
913 if (limit_result != -1)
914 fd_devpoll = open("/dev/poll", O_RDWR);
915 Py_END_ALLOW_THREADS
916
917 if (limit_result == -1) {
918 PyErr_SetFromErrno(PyExc_OSError);
919 return NULL;
920 }
921 if (fd_devpoll == -1) {
922 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
923 return NULL;
924 }
925
926 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
927 if (fds == NULL) {
928 close(fd_devpoll);
929 PyErr_NoMemory();
930 return NULL;
931 }
932
933 self = PyObject_New(devpollObject, &devpoll_Type);
934 if (self == NULL) {
935 close(fd_devpoll);
936 PyMem_DEL(fds);
937 return NULL;
938 }
939 self->fd_devpoll = fd_devpoll;
940 self->max_n_fds = limit.rlim_cur;
941 self->n_fds = 0;
942 self->fds = fds;
943
944 return self;
945}
946
947static void
948devpoll_dealloc(devpollObject *self)
949{
950 Py_BEGIN_ALLOW_THREADS
951 close(self->fd_devpoll);
952 Py_END_ALLOW_THREADS
953
954 PyMem_DEL(self->fds);
955
956 PyObject_Del(self);
957}
958
959static PyTypeObject devpoll_Type = {
960 /* The ob_type field must be initialized in the module init function
961 * to be portable to Windows without using C++. */
962 PyVarObject_HEAD_INIT(NULL, 0)
963 "select.devpoll", /*tp_name*/
964 sizeof(devpollObject), /*tp_basicsize*/
965 0, /*tp_itemsize*/
966 /* methods */
967 (destructor)devpoll_dealloc, /*tp_dealloc*/
968 0, /*tp_print*/
969 0, /*tp_getattr*/
970 0, /*tp_setattr*/
971 0, /*tp_reserved*/
972 0, /*tp_repr*/
973 0, /*tp_as_number*/
974 0, /*tp_as_sequence*/
975 0, /*tp_as_mapping*/
976 0, /*tp_hash*/
977 0, /*tp_call*/
978 0, /*tp_str*/
979 0, /*tp_getattro*/
980 0, /*tp_setattro*/
981 0, /*tp_as_buffer*/
982 Py_TPFLAGS_DEFAULT, /*tp_flags*/
983 0, /*tp_doc*/
984 0, /*tp_traverse*/
985 0, /*tp_clear*/
986 0, /*tp_richcompare*/
987 0, /*tp_weaklistoffset*/
988 0, /*tp_iter*/
989 0, /*tp_iternext*/
990 devpoll_methods, /*tp_methods*/
991};
992#endif /* HAVE_SYS_DEVPOLL_H */
993
994
995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000996PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000997"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000998unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000999
1000static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001001select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001004}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005
Jesus Cead8b9ae62011-11-14 19:07:41 +01001006#ifdef HAVE_SYS_DEVPOLL_H
1007PyDoc_STRVAR(devpoll_doc,
1008"Returns a polling object, which supports registering and\n\
1009unregistering file descriptors, and then polling them for I/O events.");
1010
1011static PyObject *
1012select_devpoll(PyObject *self, PyObject *unused)
1013{
1014 return (PyObject *)newDevPollObject();
1015}
1016#endif
1017
1018
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001021 * On some systems poll() sets errno on invalid file descriptors. We test
1022 * for this at runtime because this bug may be fixed or introduced between
1023 * OS releases.
1024 */
1025static int select_have_broken_poll(void)
1026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 int poll_test;
1028 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 /* Create a file descriptor to make invalid */
1033 if (pipe(filedes) < 0) {
1034 return 1;
1035 }
1036 poll_struct.fd = filedes[0];
1037 close(filedes[0]);
1038 close(filedes[1]);
1039 poll_test = poll(&poll_struct, 1, 0);
1040 if (poll_test < 0) {
1041 return 1;
1042 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1043 return 1;
1044 }
1045 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001046}
1047#endif /* __APPLE__ */
1048
1049#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001050
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001051#ifdef HAVE_EPOLL
1052/* **************************************************************************
1053 * epoll interface for Linux 2.6
1054 *
1055 * Written by Christian Heimes
1056 * Inspired by Twisted's _epoll.pyx and select.poll()
1057 */
1058
1059#ifdef HAVE_SYS_EPOLL_H
1060#include <sys/epoll.h>
1061#endif
1062
1063typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001065 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001066} pyEpoll_Object;
1067
1068static PyTypeObject pyEpoll_Type;
1069#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1070
1071static PyObject *
1072pyepoll_err_closed(void)
1073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1075 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001076}
1077
1078static int
1079pyepoll_internal_close(pyEpoll_Object *self)
1080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 int save_errno = 0;
1082 if (self->epfd >= 0) {
1083 int epfd = self->epfd;
1084 self->epfd = -1;
1085 Py_BEGIN_ALLOW_THREADS
1086 if (close(epfd) < 0)
1087 save_errno = errno;
1088 Py_END_ALLOW_THREADS
1089 }
1090 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001091}
1092
1093static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001094newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 assert(type != NULL && type->tp_alloc != NULL);
1099 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1100 if (self == NULL)
1101 return NULL;
1102
1103 if (fd == -1) {
1104 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001105#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001106 if (flags)
1107 self->epfd = epoll_create1(flags);
1108 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001109#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001110 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 Py_END_ALLOW_THREADS
1112 }
1113 else {
1114 self->epfd = fd;
1115 }
1116 if (self->epfd < 0) {
1117 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001118 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 return NULL;
1120 }
1121 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001122}
1123
1124
1125static PyObject *
1126pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1127{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001128 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001129 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001130
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001131 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1132 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001134 if (sizehint < 0) {
1135 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1136 return NULL;
1137 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001138
Benjamin Peterson95c16622011-12-27 15:36:32 -06001139 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001140}
1141
1142
1143static void
1144pyepoll_dealloc(pyEpoll_Object *self)
1145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 (void)pyepoll_internal_close(self);
1147 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001148}
1149
1150static PyObject*
1151pyepoll_close(pyEpoll_Object *self)
1152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 errno = pyepoll_internal_close(self);
1154 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001155 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 return NULL;
1157 }
1158 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001159}
1160
1161PyDoc_STRVAR(pyepoll_close_doc,
1162"close() -> None\n\
1163\n\
1164Close the epoll control file descriptor. Further operations on the epoll\n\
1165object will raise an exception.");
1166
1167static PyObject*
1168pyepoll_get_closed(pyEpoll_Object *self)
1169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 if (self->epfd < 0)
1171 Py_RETURN_TRUE;
1172 else
1173 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001174}
1175
1176static PyObject*
1177pyepoll_fileno(pyEpoll_Object *self)
1178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 if (self->epfd < 0)
1180 return pyepoll_err_closed();
1181 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001182}
1183
1184PyDoc_STRVAR(pyepoll_fileno_doc,
1185"fileno() -> int\n\
1186\n\
1187Return the epoll control file descriptor.");
1188
1189static PyObject*
1190pyepoll_fromfd(PyObject *cls, PyObject *args)
1191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1195 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001196
Benjamin Peterson95c16622011-12-27 15:36:32 -06001197 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001198}
1199
1200PyDoc_STRVAR(pyepoll_fromfd_doc,
1201"fromfd(fd) -> epoll\n\
1202\n\
1203Create an epoll object from a given control fd.");
1204
1205static PyObject *
1206pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 struct epoll_event ev;
1209 int result;
1210 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 if (epfd < 0)
1213 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 fd = PyObject_AsFileDescriptor(pfd);
1216 if (fd == -1) {
1217 return NULL;
1218 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 switch(op) {
1221 case EPOLL_CTL_ADD:
1222 case EPOLL_CTL_MOD:
1223 ev.events = events;
1224 ev.data.fd = fd;
1225 Py_BEGIN_ALLOW_THREADS
1226 result = epoll_ctl(epfd, op, fd, &ev);
1227 Py_END_ALLOW_THREADS
1228 break;
1229 case EPOLL_CTL_DEL:
1230 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1231 * operation required a non-NULL pointer in event, even
1232 * though this argument is ignored. */
1233 Py_BEGIN_ALLOW_THREADS
1234 result = epoll_ctl(epfd, op, fd, &ev);
1235 if (errno == EBADF) {
1236 /* fd already closed */
1237 result = 0;
1238 errno = 0;
1239 }
1240 Py_END_ALLOW_THREADS
1241 break;
1242 default:
1243 result = -1;
1244 errno = EINVAL;
1245 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001248 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 return NULL;
1250 }
1251 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001252}
1253
1254static PyObject *
1255pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 PyObject *pfd;
1258 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1259 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1262 &pfd, &events)) {
1263 return NULL;
1264 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001267}
1268
1269PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001270"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001271\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001272Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001273fd is the target file descriptor of the operation.\n\
1274events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001275is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1276\n\
1277The epoll interface supports all file descriptors that support poll.");
1278
1279static PyObject *
1280pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 PyObject *pfd;
1283 unsigned int events;
1284 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1287 &pfd, &events)) {
1288 return NULL;
1289 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001292}
1293
1294PyDoc_STRVAR(pyepoll_modify_doc,
1295"modify(fd, eventmask) -> None\n\
1296\n\
1297fd is the target file descriptor of the operation\n\
1298events is a bit set composed of the various EPOLL constants");
1299
1300static PyObject *
1301pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 PyObject *pfd;
1304 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1307 &pfd)) {
1308 return NULL;
1309 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001312}
1313
1314PyDoc_STRVAR(pyepoll_unregister_doc,
1315"unregister(fd) -> None\n\
1316\n\
1317fd is the target file descriptor of the operation.");
1318
1319static PyObject *
1320pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 double dtimeout = -1.;
1323 int timeout;
1324 int maxevents = -1;
1325 int nfds, i;
1326 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001327 struct epoll_event *evs = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 if (self->epfd < 0)
1331 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1334 &dtimeout, &maxevents)) {
1335 return NULL;
1336 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 if (dtimeout < 0) {
1339 timeout = -1;
1340 }
1341 else if (dtimeout * 1000.0 > INT_MAX) {
1342 PyErr_SetString(PyExc_OverflowError,
1343 "timeout is too large");
1344 return NULL;
1345 }
1346 else {
1347 timeout = (int)(dtimeout * 1000.0);
1348 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001351 maxevents = FD_SETSIZE-1;
1352 }
1353 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 PyErr_Format(PyExc_ValueError,
1355 "maxevents must be greater than 0, got %d",
1356 maxevents);
1357 return NULL;
1358 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001360 evs = PyMem_New(struct epoll_event, maxevents);
1361 if (evs == NULL) {
1362 Py_DECREF(self);
1363 PyErr_NoMemory();
1364 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 Py_BEGIN_ALLOW_THREADS
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001368 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 Py_END_ALLOW_THREADS
1370 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001371 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 goto error;
1373 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 elist = PyList_New(nfds);
1376 if (elist == NULL) {
1377 goto error;
1378 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001381 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 if (etuple == NULL) {
1383 Py_CLEAR(elist);
1384 goto error;
1385 }
1386 PyList_SET_ITEM(elist, i, etuple);
1387 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388
Christian Heimesf6cd9672008-03-26 13:45:42 +00001389 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001390 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001392}
1393
1394PyDoc_STRVAR(pyepoll_poll_doc,
1395"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1396\n\
1397Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1398in seconds (as float). -1 makes poll wait indefinitely.\n\
1399Up to maxevents are returned to the caller.");
1400
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001401static PyObject *
1402pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1403{
1404 if (self->epfd < 0)
1405 return pyepoll_err_closed();
1406
1407 Py_INCREF(self);
1408 return (PyObject *)self;
1409}
1410
1411static PyObject *
1412pyepoll_exit(PyObject *self, PyObject *args)
1413{
1414 _Py_IDENTIFIER(close);
1415
1416 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1417}
1418
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001419static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 {"fromfd", (PyCFunction)pyepoll_fromfd,
1421 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1422 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1423 pyepoll_close_doc},
1424 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1425 pyepoll_fileno_doc},
1426 {"modify", (PyCFunction)pyepoll_modify,
1427 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1428 {"register", (PyCFunction)pyepoll_register,
1429 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1430 {"unregister", (PyCFunction)pyepoll_unregister,
1431 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1432 {"poll", (PyCFunction)pyepoll_poll,
1433 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001434 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1435 NULL},
1436 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1437 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439};
1440
1441static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 {"closed", (getter)pyepoll_get_closed, NULL,
1443 "True if the epoll handler is closed"},
1444 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001445};
1446
1447PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001448"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001449\n\
1450Returns an epolling object\n\
1451\n\
1452sizehint must be a positive integer or -1 for the default size. The\n\
1453sizehint is used to optimize internal data structures. It doesn't limit\n\
1454the maximum number of monitored events.");
1455
1456static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 PyVarObject_HEAD_INIT(NULL, 0)
1458 "select.epoll", /* tp_name */
1459 sizeof(pyEpoll_Object), /* tp_basicsize */
1460 0, /* tp_itemsize */
1461 (destructor)pyepoll_dealloc, /* tp_dealloc */
1462 0, /* tp_print */
1463 0, /* tp_getattr */
1464 0, /* tp_setattr */
1465 0, /* tp_reserved */
1466 0, /* tp_repr */
1467 0, /* tp_as_number */
1468 0, /* tp_as_sequence */
1469 0, /* tp_as_mapping */
1470 0, /* tp_hash */
1471 0, /* tp_call */
1472 0, /* tp_str */
1473 PyObject_GenericGetAttr, /* tp_getattro */
1474 0, /* tp_setattro */
1475 0, /* tp_as_buffer */
1476 Py_TPFLAGS_DEFAULT, /* tp_flags */
1477 pyepoll_doc, /* tp_doc */
1478 0, /* tp_traverse */
1479 0, /* tp_clear */
1480 0, /* tp_richcompare */
1481 0, /* tp_weaklistoffset */
1482 0, /* tp_iter */
1483 0, /* tp_iternext */
1484 pyepoll_methods, /* tp_methods */
1485 0, /* tp_members */
1486 pyepoll_getsetlist, /* tp_getset */
1487 0, /* tp_base */
1488 0, /* tp_dict */
1489 0, /* tp_descr_get */
1490 0, /* tp_descr_set */
1491 0, /* tp_dictoffset */
1492 0, /* tp_init */
1493 0, /* tp_alloc */
1494 pyepoll_new, /* tp_new */
1495 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001496};
1497
1498#endif /* HAVE_EPOLL */
1499
1500#ifdef HAVE_KQUEUE
1501/* **************************************************************************
1502 * kqueue interface for BSD
1503 *
1504 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1505 * All rights reserved.
1506 *
1507 * Redistribution and use in source and binary forms, with or without
1508 * modification, are permitted provided that the following conditions
1509 * are met:
1510 * 1. Redistributions of source code must retain the above copyright
1511 * notice, this list of conditions and the following disclaimer.
1512 * 2. Redistributions in binary form must reproduce the above copyright
1513 * notice, this list of conditions and the following disclaimer in the
1514 * documentation and/or other materials provided with the distribution.
1515 *
1516 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1517 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1518 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1519 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1520 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1521 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1522 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1523 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1524 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1525 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1526 * SUCH DAMAGE.
1527 */
1528
1529#ifdef HAVE_SYS_EVENT_H
1530#include <sys/event.h>
1531#endif
1532
1533PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001534"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001535\n\
1536This object is the equivalent of the struct kevent for the C API.\n\
1537\n\
1538See the kqueue manpage for more detailed information about the meaning\n\
1539of the arguments.\n\
1540\n\
1541One minor note: while you might hope that udata could store a\n\
1542reference to a python object, it cannot, because it is impossible to\n\
1543keep a proper reference count of the object once it's passed into the\n\
1544kernel. Therefore, I have restricted it to only storing an integer. I\n\
1545recommend ignoring it and simply using the 'ident' field to key off\n\
1546of. You could also set up a dictionary on the python side to store a\n\
1547udata->object mapping.");
1548
1549typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 PyObject_HEAD
1551 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552} kqueue_event_Object;
1553
1554static PyTypeObject kqueue_event_Type;
1555
1556#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1557
1558typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 PyObject_HEAD
1560 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001561} kqueue_queue_Object;
1562
1563static PyTypeObject kqueue_queue_Type;
1564
1565#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1566
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001567#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1568# error uintptr_t does not match void *!
1569#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1570# define T_UINTPTRT T_ULONGLONG
1571# define T_INTPTRT T_LONGLONG
1572# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1573# define UINTPTRT_FMT_UNIT "K"
1574# define INTPTRT_FMT_UNIT "L"
1575#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1576# define T_UINTPTRT T_ULONG
1577# define T_INTPTRT T_LONG
1578# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1579# define UINTPTRT_FMT_UNIT "k"
1580# define INTPTRT_FMT_UNIT "l"
1581#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1582# define T_UINTPTRT T_UINT
1583# define T_INTPTRT T_INT
1584# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1585# define UINTPTRT_FMT_UNIT "I"
1586# define INTPTRT_FMT_UNIT "i"
1587#else
1588# error uintptr_t does not match int, long, or long long!
1589#endif
1590
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001591/*
1592 * kevent is not standard and its members vary across BSDs.
1593 */
1594#if !defined(__OpenBSD__)
1595# define IDENT_TYPE T_UINTPTRT
1596# define IDENT_CAST Py_intptr_t
1597# define DATA_TYPE T_INTPTRT
1598# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1599# define IDENT_AsType PyLong_AsUintptr_t
1600#else
1601# define IDENT_TYPE T_UINT
1602# define IDENT_CAST int
1603# define DATA_TYPE T_INT
1604# define DATA_FMT_UNIT "i"
1605# define IDENT_AsType PyLong_AsUnsignedLong
1606#endif
1607
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001608/* Unfortunately, we can't store python objects in udata, because
1609 * kevents in the kernel can be removed without warning, which would
1610 * forever lose the refcount on the object stored with it.
1611 */
1612
1613#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1614static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001615 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 {"filter", T_SHORT, KQ_OFF(e.filter)},
1617 {"flags", T_USHORT, KQ_OFF(e.flags)},
1618 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001619 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1621 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001622};
1623#undef KQ_OFF
1624
1625static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001626
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001627kqueue_event_repr(kqueue_event_Object *s)
1628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 char buf[1024];
1630 PyOS_snprintf(
1631 buf, sizeof(buf),
1632 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1633 "data=0x%zd udata=%p>",
1634 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1635 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1636 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001637}
1638
1639static int
1640kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 PyObject *pfd;
1643 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1644 "data", "udata", NULL};
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001645 static char *fmt = "O|hhi" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1650 &pfd, &(self->e.filter), &(self->e.flags),
1651 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1652 return -1;
1653 }
1654
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001655 if (PyLong_Check(pfd)
1656#if IDENT_TYPE == T_UINT
1657 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1658#endif
1659 ) {
1660 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 }
1662 else {
1663 self->e.ident = PyObject_AsFileDescriptor(pfd);
1664 }
1665 if (PyErr_Occurred()) {
1666 return -1;
1667 }
1668 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001669}
1670
1671static PyObject *
1672kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 if (!kqueue_event_Check(o)) {
1678 if (op == Py_EQ || op == Py_NE) {
1679 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1680 Py_INCREF(res);
1681 return res;
1682 }
1683 PyErr_Format(PyExc_TypeError,
1684 "can't compare %.200s to %.200s",
1685 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1686 return NULL;
1687 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001688 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 ((result = s->e.filter - o->e.filter) == 0) &&
1690 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001691 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 ((result = s->e.data - o->e.data) == 0) &&
1693 ((result = s->e.udata - o->e.udata) == 0)
1694 ) {
1695 result = 0;
1696 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 switch (op) {
1699 case Py_EQ:
1700 result = (result == 0);
1701 break;
1702 case Py_NE:
1703 result = (result != 0);
1704 break;
1705 case Py_LE:
1706 result = (result <= 0);
1707 break;
1708 case Py_GE:
1709 result = (result >= 0);
1710 break;
1711 case Py_LT:
1712 result = (result < 0);
1713 break;
1714 case Py_GT:
1715 result = (result > 0);
1716 break;
1717 }
1718 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001719}
1720
1721static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 PyVarObject_HEAD_INIT(NULL, 0)
1723 "select.kevent", /* tp_name */
1724 sizeof(kqueue_event_Object), /* tp_basicsize */
1725 0, /* tp_itemsize */
1726 0, /* tp_dealloc */
1727 0, /* tp_print */
1728 0, /* tp_getattr */
1729 0, /* tp_setattr */
1730 0, /* tp_reserved */
1731 (reprfunc)kqueue_event_repr, /* tp_repr */
1732 0, /* tp_as_number */
1733 0, /* tp_as_sequence */
1734 0, /* tp_as_mapping */
1735 0, /* tp_hash */
1736 0, /* tp_call */
1737 0, /* tp_str */
1738 0, /* tp_getattro */
1739 0, /* tp_setattro */
1740 0, /* tp_as_buffer */
1741 Py_TPFLAGS_DEFAULT, /* tp_flags */
1742 kqueue_event_doc, /* tp_doc */
1743 0, /* tp_traverse */
1744 0, /* tp_clear */
1745 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1746 0, /* tp_weaklistoffset */
1747 0, /* tp_iter */
1748 0, /* tp_iternext */
1749 0, /* tp_methods */
1750 kqueue_event_members, /* tp_members */
1751 0, /* tp_getset */
1752 0, /* tp_base */
1753 0, /* tp_dict */
1754 0, /* tp_descr_get */
1755 0, /* tp_descr_set */
1756 0, /* tp_dictoffset */
1757 (initproc)kqueue_event_init, /* tp_init */
1758 0, /* tp_alloc */
1759 0, /* tp_new */
1760 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001761};
1762
1763static PyObject *
1764kqueue_queue_err_closed(void)
1765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1767 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001768}
1769
1770static int
1771kqueue_queue_internal_close(kqueue_queue_Object *self)
1772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 int save_errno = 0;
1774 if (self->kqfd >= 0) {
1775 int kqfd = self->kqfd;
1776 self->kqfd = -1;
1777 Py_BEGIN_ALLOW_THREADS
1778 if (close(kqfd) < 0)
1779 save_errno = errno;
1780 Py_END_ALLOW_THREADS
1781 }
1782 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001783}
1784
1785static PyObject *
1786newKqueue_Object(PyTypeObject *type, SOCKET fd)
1787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 kqueue_queue_Object *self;
1789 assert(type != NULL && type->tp_alloc != NULL);
1790 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1791 if (self == NULL) {
1792 return NULL;
1793 }
1794
1795 if (fd == -1) {
1796 Py_BEGIN_ALLOW_THREADS
1797 self->kqfd = kqueue();
1798 Py_END_ALLOW_THREADS
1799 }
1800 else {
1801 self->kqfd = fd;
1802 }
1803 if (self->kqfd < 0) {
1804 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001805 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 return NULL;
1807 }
1808 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001809}
1810
1811static PyObject *
1812kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1813{
1814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 if ((args != NULL && PyObject_Size(args)) ||
1816 (kwds != NULL && PyObject_Size(kwds))) {
1817 PyErr_SetString(PyExc_ValueError,
1818 "select.kqueue doesn't accept arguments");
1819 return NULL;
1820 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001823}
1824
1825static void
1826kqueue_queue_dealloc(kqueue_queue_Object *self)
1827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 kqueue_queue_internal_close(self);
1829 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001830}
1831
1832static PyObject*
1833kqueue_queue_close(kqueue_queue_Object *self)
1834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 errno = kqueue_queue_internal_close(self);
1836 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001837 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 return NULL;
1839 }
1840 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841}
1842
1843PyDoc_STRVAR(kqueue_queue_close_doc,
1844"close() -> None\n\
1845\n\
1846Close the kqueue control file descriptor. Further operations on the kqueue\n\
1847object will raise an exception.");
1848
1849static PyObject*
1850kqueue_queue_get_closed(kqueue_queue_Object *self)
1851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 if (self->kqfd < 0)
1853 Py_RETURN_TRUE;
1854 else
1855 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856}
1857
1858static PyObject*
1859kqueue_queue_fileno(kqueue_queue_Object *self)
1860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (self->kqfd < 0)
1862 return kqueue_queue_err_closed();
1863 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001864}
1865
1866PyDoc_STRVAR(kqueue_queue_fileno_doc,
1867"fileno() -> int\n\
1868\n\
1869Return the kqueue control file descriptor.");
1870
1871static PyObject*
1872kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1877 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880}
1881
1882PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1883"fromfd(fd) -> kqueue\n\
1884\n\
1885Create a kqueue object from a given control fd.");
1886
1887static PyObject *
1888kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 int nevents = 0;
1891 int gotevents = 0;
1892 int nchanges = 0;
1893 int i = 0;
1894 PyObject *otimeout = NULL;
1895 PyObject *ch = NULL;
1896 PyObject *it = NULL, *ei = NULL;
1897 PyObject *result = NULL;
1898 struct kevent *evl = NULL;
1899 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001900 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 if (self->kqfd < 0)
1904 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1907 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 if (nevents < 0) {
1910 PyErr_Format(PyExc_ValueError,
1911 "Length of eventlist must be 0 or positive, got %d",
1912 nevents);
1913 return NULL;
1914 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 if (otimeout == Py_None || otimeout == NULL) {
1917 ptimeoutspec = NULL;
1918 }
1919 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001920 if (_PyTime_ObjectToTimespec(otimeout,
1921 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1922 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001923
Victor Stinner5d272cc2012-03-13 13:35:55 +01001924 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 PyErr_SetString(PyExc_ValueError,
1926 "timeout must be positive or None");
1927 return NULL;
1928 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001929 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 }
1931 else {
1932 PyErr_Format(PyExc_TypeError,
1933 "timeout argument must be an number "
1934 "or None, got %.200s",
1935 Py_TYPE(otimeout)->tp_name);
1936 return NULL;
1937 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 if (ch != NULL && ch != Py_None) {
1940 it = PyObject_GetIter(ch);
1941 if (it == NULL) {
1942 PyErr_SetString(PyExc_TypeError,
1943 "changelist is not iterable");
1944 return NULL;
1945 }
1946 nchanges = PyObject_Size(ch);
1947 if (nchanges < 0) {
1948 goto error;
1949 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 chl = PyMem_New(struct kevent, nchanges);
1952 if (chl == NULL) {
1953 PyErr_NoMemory();
1954 goto error;
1955 }
1956 i = 0;
1957 while ((ei = PyIter_Next(it)) != NULL) {
1958 if (!kqueue_event_Check(ei)) {
1959 Py_DECREF(ei);
1960 PyErr_SetString(PyExc_TypeError,
1961 "changelist must be an iterable of "
1962 "select.kevent objects");
1963 goto error;
1964 } else {
1965 chl[i++] = ((kqueue_event_Object *)ei)->e;
1966 }
1967 Py_DECREF(ei);
1968 }
1969 }
1970 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 /* event list */
1973 if (nevents) {
1974 evl = PyMem_New(struct kevent, nevents);
1975 if (evl == NULL) {
1976 PyErr_NoMemory();
1977 goto error;
1978 }
1979 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 Py_BEGIN_ALLOW_THREADS
1982 gotevents = kevent(self->kqfd, chl, nchanges,
1983 evl, nevents, ptimeoutspec);
1984 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 if (gotevents == -1) {
1987 PyErr_SetFromErrno(PyExc_OSError);
1988 goto error;
1989 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 result = PyList_New(gotevents);
1992 if (result == NULL) {
1993 goto error;
1994 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 for (i = 0; i < gotevents; i++) {
1997 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2000 if (ch == NULL) {
2001 goto error;
2002 }
2003 ch->e = evl[i];
2004 PyList_SET_ITEM(result, i, (PyObject *)ch);
2005 }
2006 PyMem_Free(chl);
2007 PyMem_Free(evl);
2008 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002009
2010 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 PyMem_Free(chl);
2012 PyMem_Free(evl);
2013 Py_XDECREF(result);
2014 Py_XDECREF(it);
2015 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002016}
2017
2018PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002019"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002020\n\
2021Calls the kernel kevent function.\n\
2022- changelist must be a list of kevent objects describing the changes\n\
2023 to be made to the kernel's watch list or None.\n\
2024- max_events lets you specify the maximum number of events that the\n\
2025 kernel will return.\n\
2026- timeout is the maximum time to wait in seconds, or else None,\n\
2027 to wait forever. timeout accepts floats for smaller timeouts, too.");
2028
2029
2030static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2032 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2033 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2034 kqueue_queue_close_doc},
2035 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2036 kqueue_queue_fileno_doc},
2037 {"control", (PyCFunction)kqueue_queue_control,
2038 METH_VARARGS , kqueue_queue_control_doc},
2039 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040};
2041
2042static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 {"closed", (getter)kqueue_queue_get_closed, NULL,
2044 "True if the kqueue handler is closed"},
2045 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002046};
2047
2048PyDoc_STRVAR(kqueue_queue_doc,
2049"Kqueue syscall wrapper.\n\
2050\n\
2051For example, to start watching a socket for input:\n\
2052>>> kq = kqueue()\n\
2053>>> sock = socket()\n\
2054>>> sock.connect((host, port))\n\
2055>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2056\n\
2057To wait one second for it to become writeable:\n\
2058>>> kq.control(None, 1, 1000)\n\
2059\n\
2060To stop listening:\n\
2061>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2062
2063static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 PyVarObject_HEAD_INIT(NULL, 0)
2065 "select.kqueue", /* tp_name */
2066 sizeof(kqueue_queue_Object), /* tp_basicsize */
2067 0, /* tp_itemsize */
2068 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2069 0, /* tp_print */
2070 0, /* tp_getattr */
2071 0, /* tp_setattr */
2072 0, /* tp_reserved */
2073 0, /* tp_repr */
2074 0, /* tp_as_number */
2075 0, /* tp_as_sequence */
2076 0, /* tp_as_mapping */
2077 0, /* tp_hash */
2078 0, /* tp_call */
2079 0, /* tp_str */
2080 0, /* tp_getattro */
2081 0, /* tp_setattro */
2082 0, /* tp_as_buffer */
2083 Py_TPFLAGS_DEFAULT, /* tp_flags */
2084 kqueue_queue_doc, /* tp_doc */
2085 0, /* tp_traverse */
2086 0, /* tp_clear */
2087 0, /* tp_richcompare */
2088 0, /* tp_weaklistoffset */
2089 0, /* tp_iter */
2090 0, /* tp_iternext */
2091 kqueue_queue_methods, /* tp_methods */
2092 0, /* tp_members */
2093 kqueue_queue_getsetlist, /* tp_getset */
2094 0, /* tp_base */
2095 0, /* tp_dict */
2096 0, /* tp_descr_get */
2097 0, /* tp_descr_set */
2098 0, /* tp_dictoffset */
2099 0, /* tp_init */
2100 0, /* tp_alloc */
2101 kqueue_queue_new, /* tp_new */
2102 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002103};
2104
2105#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002106
2107
2108
2109
2110
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002111/* ************************************************************************ */
2112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002114"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2115\n\
2116Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002117The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002118rlist -- wait until ready for reading\n\
2119wlist -- wait until ready for writing\n\
2120xlist -- wait for an ``exceptional condition''\n\
2121If only one kind of condition is required, pass [] for the other lists.\n\
2122A file descriptor is either a socket or file object, or a small integer\n\
2123gotten from a fileno() method call on one of those.\n\
2124\n\
2125The optional 4th argument specifies a timeout in seconds; it may be\n\
2126a floating point number to specify fractions of seconds. If it is absent\n\
2127or None, the call will never time out.\n\
2128\n\
2129The return value is a tuple of three lists corresponding to the first three\n\
2130arguments; each contains the subset of the corresponding file descriptors\n\
2131that are ready.\n\
2132\n\
2133*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002134On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002135descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002136
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002137static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002139#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002141#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002142#ifdef HAVE_SYS_DEVPOLL_H
2143 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2144#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002146};
2147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002148PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002149"This module supports asynchronous I/O on multiple file descriptors.\n\
2150\n\
2151*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002152On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002153
Martin v. Löwis1a214512008-06-11 05:26:20 +00002154
2155static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 PyModuleDef_HEAD_INIT,
2157 "select",
2158 module_doc,
2159 -1,
2160 select_methods,
2161 NULL,
2162 NULL,
2163 NULL,
2164 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002165};
2166
Jesus Cead8b9ae62011-11-14 19:07:41 +01002167
2168
2169
Mark Hammond62b1ab12002-07-23 06:31:15 +00002170PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002171PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002172{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 PyObject *m;
2174 m = PyModule_Create(&selectmodule);
2175 if (m == NULL)
2176 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002177
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002178 Py_INCREF(PyExc_OSError);
2179 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002180
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002181#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002182#ifdef HAVE_BROKEN_PIPE_BUF
2183#undef PIPE_BUF
2184#define PIPE_BUF 512
2185#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002186 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002187#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002188
Charles-François Natali986a56c2013-01-19 12:19:10 +01002189#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002190#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 if (select_have_broken_poll()) {
2192 if (PyObject_DelAttrString(m, "poll") == -1) {
2193 PyErr_Clear();
2194 }
2195 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002196#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002198#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 if (PyType_Ready(&poll_Type) < 0)
2200 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002201 PyModule_AddIntMacro(m, POLLIN);
2202 PyModule_AddIntMacro(m, POLLPRI);
2203 PyModule_AddIntMacro(m, POLLOUT);
2204 PyModule_AddIntMacro(m, POLLERR);
2205 PyModule_AddIntMacro(m, POLLHUP);
2206 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002207
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002208#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002209 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002210#endif
2211#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002212 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002213#endif
2214#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002215 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002216#endif
2217#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002218 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002219#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002220#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002221 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002222#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002223 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002224#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002225
Jesus Cead8b9ae62011-11-14 19:07:41 +01002226#ifdef HAVE_SYS_DEVPOLL_H
2227 if (PyType_Ready(&devpoll_Type) < 0)
2228 return NULL;
2229#endif
2230
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2233 if (PyType_Ready(&pyEpoll_Type) < 0)
2234 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002236 Py_INCREF(&pyEpoll_Type);
2237 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002238
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002239 PyModule_AddIntMacro(m, EPOLLIN);
2240 PyModule_AddIntMacro(m, EPOLLOUT);
2241 PyModule_AddIntMacro(m, EPOLLPRI);
2242 PyModule_AddIntMacro(m, EPOLLERR);
2243 PyModule_AddIntMacro(m, EPOLLHUP);
2244 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002245#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002247 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002248#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002250 PyModule_AddIntMacro(m, EPOLLRDNORM);
2251 PyModule_AddIntMacro(m, EPOLLRDBAND);
2252 PyModule_AddIntMacro(m, EPOLLWRNORM);
2253 PyModule_AddIntMacro(m, EPOLLWRBAND);
2254 PyModule_AddIntMacro(m, EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002255
Benjamin Peterson95c16622011-12-27 15:36:32 -06002256#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002257 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002258#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259#endif /* HAVE_EPOLL */
2260
2261#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 kqueue_event_Type.tp_new = PyType_GenericNew;
2263 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2264 if(PyType_Ready(&kqueue_event_Type) < 0)
2265 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 Py_INCREF(&kqueue_event_Type);
2268 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2271 if(PyType_Ready(&kqueue_queue_Type) < 0)
2272 return NULL;
2273 Py_INCREF(&kqueue_queue_Type);
2274 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2275
2276 /* event filters */
2277 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2278 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2279 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2280 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2281 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002282#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002284#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2286 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 /* event flags */
2289 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2290 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2291 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2292 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2293 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2294 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2297 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2300 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 /* READ WRITE filter flag */
2303 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 /* VNODE filter flags */
2306 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2307 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2308 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2309 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2310 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2311 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2312 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 /* PROC filter flags */
2315 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2316 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2317 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2318 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2319 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2322 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2323 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2324
2325 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002326#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2328 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2329 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002330#endif
2331
2332#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002333 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002334}