blob: 9128ea367b7aa9aad2bc6c016e44b2d9839edf11 [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;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000087 Py_ssize_t i, len = -1;
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
98 len = PySequence_Fast_GET_SIZE(fast_seq);
99
100 for (i = 0; i < len; i++) {
101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200105 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 Py_INCREF(o);
108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200114 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
134 }
135 Py_DECREF(fast_seq);
136 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137
138 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 Py_XDECREF(o);
140 Py_DECREF(fast_seq);
141 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000142}
143
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144/* returns NULL and sets the Python exception if an error occurred */
145static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000146set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 int i, j, count=0;
149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
153 if (FD_ISSET(fd2obj[j].fd, set))
154 count++;
155 }
156 list = PyList_New(count);
157 if (!list)
158 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 o = fd2obj[j].obj;
165 fd2obj[j].obj = NULL;
166 /* transfer ownership */
167 if (PyList_SetItem(list, i, o) < 0)
168 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 i++;
171 }
172 }
173 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 Py_DECREF(list);
176 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000177}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000178
Barry Warsawb44740f2001-08-16 16:52:59 +0000179#undef SELECT_USES_HEAP
180#if FD_SETSIZE > 1024
181#define SELECT_USES_HEAP
182#endif /* FD_SETSIZE > 1024 */
183
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000184static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000185select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000186{
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000189#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 /* XXX: All this should probably be implemented as follows:
191 * - find the highest descriptor we're interested in
192 * - add one
193 * - that's the size
194 * See: Stevens, APitUE, $12.5.1
195 */
196 pylist rfd2obj[FD_SETSIZE + 1];
197 pylist wfd2obj[FD_SETSIZE + 1];
198 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000199#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 PyObject *ifdlist, *ofdlist, *efdlist;
201 PyObject *ret = NULL;
202 PyObject *tout = Py_None;
203 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 int imax, omax, emax, max;
206 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 /* convert arguments */
209 if (!PyArg_UnpackTuple(args, "select", 3, 4,
210 &ifdlist, &ofdlist, &efdlist, &tout))
211 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 if (tout == Py_None)
214 tvp = (struct timeval *)0;
215 else if (!PyNumber_Check(tout)) {
216 PyErr_SetString(PyExc_TypeError,
217 "timeout must be a float or None");
218 return NULL;
219 }
220 else {
Victor Stinnerb2a37732012-03-14 00:20:51 +0100221#ifdef MS_WINDOWS
222 time_t sec;
223 if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 return NULL;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100225 assert(sizeof(tv.tv_sec) == sizeof(long));
226#if SIZEOF_TIME_T > SIZEOF_LONG
227 if (sec > LONG_MAX) {
228 PyErr_SetString(PyExc_OverflowError,
229 "timeout is too large");
230 return NULL;
231 }
232#endif
233 tv.tv_sec = (long)sec;
234#else
Brett Cannon8798ad32012-04-07 14:59:29 -0400235 /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4
236 bytes as required), but no longer defined by a long. */
Benjamin Peterson6f3e5e42012-09-11 12:05:05 -0400237 long tv_usec;
Brett Cannon8798ad32012-04-07 14:59:29 -0400238 if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1)
Victor Stinnerb2a37732012-03-14 00:20:51 +0100239 return NULL;
Brett Cannon8798ad32012-04-07 14:59:29 -0400240 tv.tv_usec = tv_usec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100241#endif
Victor Stinner5d272cc2012-03-13 13:35:55 +0100242 if (tv.tv_sec < 0) {
243 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 return NULL;
245 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 tvp = &tv;
247 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000248
Guido van Rossumed233a51992-06-23 09:07:03 +0000249
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 /* Allocate memory for the lists */
252 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
255 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
256 if (rfd2obj) PyMem_DEL(rfd2obj);
257 if (wfd2obj) PyMem_DEL(wfd2obj);
258 if (efd2obj) PyMem_DEL(efd2obj);
259 return PyErr_NoMemory();
260 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000261#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 /* Convert sequences to fd_sets, and get maximum fd number
263 * propagates the Python exception set in seq2set()
264 */
265 rfd2obj[0].sentinel = -1;
266 wfd2obj[0].sentinel = -1;
267 efd2obj[0].sentinel = -1;
268 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
269 goto finally;
270 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
271 goto finally;
272 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
273 goto finally;
274 max = imax;
275 if (omax > max) max = omax;
276 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 Py_BEGIN_ALLOW_THREADS
279 n = select(max, &ifdset, &ofdset, &efdset, tvp);
280 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000281
Thomas Heller106f4c72002-09-24 16:51:00 +0000282#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200284 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000286#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200288 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000290#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 else {
292 /* any of these three calls can raise an exception. it's more
293 convenient to test for this after all three calls... but
294 is that acceptable?
295 */
296 ifdlist = set2list(&ifdset, rfd2obj);
297 ofdlist = set2list(&ofdset, wfd2obj);
298 efdlist = set2list(&efdset, efd2obj);
299 if (PyErr_Occurred())
300 ret = NULL;
301 else
302 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 Py_DECREF(ifdlist);
305 Py_DECREF(ofdlist);
306 Py_DECREF(efdlist);
307 }
308
Barry Warsawc1cb3601996-12-12 22:16:21 +0000309 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 reap_obj(rfd2obj);
311 reap_obj(wfd2obj);
312 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000313#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 PyMem_DEL(rfd2obj);
315 PyMem_DEL(wfd2obj);
316 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000317#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000319}
320
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000321#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323 * poll() support
324 */
325
326typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 PyObject_HEAD
328 PyObject *dict;
329 int ufd_uptodate;
330 int ufd_len;
331 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000332} pollObject;
333
Jeremy Hylton938ace62002-07-17 16:30:39 +0000334static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337 contained within a pollObject. Return 1 on success, 0 on an error.
338*/
339
340static int
341update_ufd_array(pollObject *self)
342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 Py_ssize_t i, pos;
344 PyObject *key, *value;
345 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 self->ufd_len = PyDict_Size(self->dict);
348 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
349 if (self->ufds == NULL) {
350 self->ufds = old_ufds;
351 PyErr_NoMemory();
352 return 0;
353 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 i = pos = 0;
356 while (PyDict_Next(self->dict, &pos, &key, &value)) {
357 self->ufds[i].fd = PyLong_AsLong(key);
358 self->ufds[i].events = (short)PyLong_AsLong(value);
359 i++;
360 }
361 self->ufd_uptodate = 1;
362 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363}
364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000365PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366"register(fd [, eventmask] ) -> None\n\n\
367Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000368fd -- either an integer, or an object with a fileno() method returning an\n\
369 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000370events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371
372static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 PyObject *o, *key, *value;
376 int fd, events = POLLIN | POLLPRI | POLLOUT;
377 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
380 return NULL;
381 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 fd = PyObject_AsFileDescriptor(o);
384 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 /* Add entry to the internal dictionary: the key is the
387 file descriptor, and the value is the event mask. */
388 key = PyLong_FromLong(fd);
389 if (key == NULL)
390 return NULL;
391 value = PyLong_FromLong(events);
392 if (value == NULL) {
393 Py_DECREF(key);
394 return NULL;
395 }
396 err = PyDict_SetItem(self->dict, key, value);
397 Py_DECREF(key);
398 Py_DECREF(value);
399 if (err < 0)
400 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 self->ufd_uptodate = 0;
403
404 Py_INCREF(Py_None);
405 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406}
407
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000408PyDoc_STRVAR(poll_modify_doc,
409"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000410Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000411fd -- either an integer, or an object with a fileno() method returning an\n\
412 int.\n\
413events -- an optional bitmask describing the type of events to check for");
414
415static PyObject *
416poll_modify(pollObject *self, PyObject *args)
417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 PyObject *o, *key, *value;
419 int fd, events;
420 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
423 return NULL;
424 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 fd = PyObject_AsFileDescriptor(o);
427 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 /* Modify registered fd */
430 key = PyLong_FromLong(fd);
431 if (key == NULL)
432 return NULL;
433 if (PyDict_GetItem(self->dict, key) == NULL) {
434 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200435 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200436 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 return NULL;
438 }
439 value = PyLong_FromLong(events);
440 if (value == NULL) {
441 Py_DECREF(key);
442 return NULL;
443 }
444 err = PyDict_SetItem(self->dict, key, value);
445 Py_DECREF(key);
446 Py_DECREF(value);
447 if (err < 0)
448 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 self->ufd_uptodate = 0;
451
452 Py_INCREF(Py_None);
453 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000454}
455
456
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000457PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000459Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000460
461static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 PyObject *key;
465 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 fd = PyObject_AsFileDescriptor( o );
468 if (fd == -1)
469 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 /* Check whether the fd is already in the array */
472 key = PyLong_FromLong(fd);
473 if (key == NULL)
474 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 if (PyDict_DelItem(self->dict, key) == -1) {
477 Py_DECREF(key);
478 /* This will simply raise the KeyError set by PyDict_DelItem
479 if the file descriptor isn't registered. */
480 return NULL;
481 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 Py_DECREF(key);
484 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 Py_INCREF(Py_None);
487 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488}
489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000490PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
492Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000493any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494
495static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 PyObject *result_list = NULL, *tout = NULL;
499 int timeout = 0, poll_result, i, j;
500 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
503 return NULL;
504 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 /* Check values for timeout */
507 if (tout == NULL || tout == Py_None)
508 timeout = -1;
509 else if (!PyNumber_Check(tout)) {
510 PyErr_SetString(PyExc_TypeError,
511 "timeout must be an integer or None");
512 return NULL;
513 }
514 else {
515 tout = PyNumber_Long(tout);
516 if (!tout)
517 return NULL;
518 timeout = PyLong_AsLong(tout);
519 Py_DECREF(tout);
520 if (timeout == -1 && PyErr_Occurred())
521 return NULL;
522 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 /* Ensure the ufd array is up to date */
525 if (!self->ufd_uptodate)
526 if (update_ufd_array(self) == 0)
527 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 /* call poll() */
530 Py_BEGIN_ALLOW_THREADS
531 poll_result = poll(self->ufds, self->ufd_len, timeout);
532 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200535 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 return NULL;
537 }
538
539 /* build the result list */
540
541 result_list = PyList_New(poll_result);
542 if (!result_list)
543 return NULL;
544 else {
545 for (i = 0, j = 0; j < poll_result; j++) {
546 /* skip to the next fired descriptor */
547 while (!self->ufds[i].revents) {
548 i++;
549 }
550 /* if we hit a NULL return, set value to NULL
551 and break out of loop; code at end will
552 clean up result_list */
553 value = PyTuple_New(2);
554 if (value == NULL)
555 goto error;
556 num = PyLong_FromLong(self->ufds[i].fd);
557 if (num == NULL) {
558 Py_DECREF(value);
559 goto error;
560 }
561 PyTuple_SET_ITEM(value, 0, num);
562
563 /* The &0xffff is a workaround for AIX. 'revents'
564 is a 16-bit short, and IBM assigned POLLNVAL
565 to be 0x8000, so the conversion to int results
566 in a negative number. See SF bug #923315. */
567 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
568 if (num == NULL) {
569 Py_DECREF(value);
570 goto error;
571 }
572 PyTuple_SET_ITEM(value, 1, num);
573 if ((PyList_SetItem(result_list, j, value)) == -1) {
574 Py_DECREF(value);
575 goto error;
576 }
577 i++;
578 }
579 }
580 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000581
582 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 Py_DECREF(result_list);
584 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000585}
586
587static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 {"register", (PyCFunction)poll_register,
589 METH_VARARGS, poll_register_doc},
590 {"modify", (PyCFunction)poll_modify,
591 METH_VARARGS, poll_modify_doc},
592 {"unregister", (PyCFunction)poll_unregister,
593 METH_O, poll_unregister_doc},
594 {"poll", (PyCFunction)poll_poll,
595 METH_VARARGS, poll_poll_doc},
596 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000597};
598
599static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000600newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 pollObject *self;
603 self = PyObject_New(pollObject, &poll_Type);
604 if (self == NULL)
605 return NULL;
606 /* ufd_uptodate is a Boolean, denoting whether the
607 array pointed to by ufds matches the contents of the dictionary. */
608 self->ufd_uptodate = 0;
609 self->ufds = NULL;
610 self->dict = PyDict_New();
611 if (self->dict == NULL) {
612 Py_DECREF(self);
613 return NULL;
614 }
615 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000616}
617
618static void
619poll_dealloc(pollObject *self)
620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 if (self->ufds != NULL)
622 PyMem_DEL(self->ufds);
623 Py_XDECREF(self->dict);
624 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000625}
626
Tim Peters0c322792002-07-17 16:49:03 +0000627static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 /* The ob_type field must be initialized in the module init function
629 * to be portable to Windows without using C++. */
630 PyVarObject_HEAD_INIT(NULL, 0)
631 "select.poll", /*tp_name*/
632 sizeof(pollObject), /*tp_basicsize*/
633 0, /*tp_itemsize*/
634 /* methods */
635 (destructor)poll_dealloc, /*tp_dealloc*/
636 0, /*tp_print*/
637 0, /*tp_getattr*/
638 0, /*tp_setattr*/
639 0, /*tp_reserved*/
640 0, /*tp_repr*/
641 0, /*tp_as_number*/
642 0, /*tp_as_sequence*/
643 0, /*tp_as_mapping*/
644 0, /*tp_hash*/
645 0, /*tp_call*/
646 0, /*tp_str*/
647 0, /*tp_getattro*/
648 0, /*tp_setattro*/
649 0, /*tp_as_buffer*/
650 Py_TPFLAGS_DEFAULT, /*tp_flags*/
651 0, /*tp_doc*/
652 0, /*tp_traverse*/
653 0, /*tp_clear*/
654 0, /*tp_richcompare*/
655 0, /*tp_weaklistoffset*/
656 0, /*tp_iter*/
657 0, /*tp_iternext*/
658 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659};
660
Jesus Cead8b9ae62011-11-14 19:07:41 +0100661#ifdef HAVE_SYS_DEVPOLL_H
662typedef struct {
663 PyObject_HEAD
664 int fd_devpoll;
665 int max_n_fds;
666 int n_fds;
667 struct pollfd *fds;
668} devpollObject;
669
670static PyTypeObject devpoll_Type;
671
672static int devpoll_flush(devpollObject *self)
673{
674 int size, n;
675
676 if (!self->n_fds) return 0;
677
678 size = sizeof(struct pollfd)*self->n_fds;
679 self->n_fds = 0;
680
681 Py_BEGIN_ALLOW_THREADS
682 n = write(self->fd_devpoll, self->fds, size);
683 Py_END_ALLOW_THREADS
684
685 if (n == -1 ) {
686 PyErr_SetFromErrno(PyExc_IOError);
687 return -1;
688 }
689 if (n < size) {
690 /*
691 ** Data writed to /dev/poll is a binary data structure. It is not
692 ** clear what to do if a partial write occurred. For now, raise
693 ** an exception and see if we actually found this problem in
694 ** the wild.
695 ** See http://bugs.python.org/issue6397.
696 */
697 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
698 "Please, report at http://bugs.python.org/. "
699 "Data to report: Size tried: %d, actual size written: %d.",
700 size, n);
701 return -1;
702 }
703 return 0;
704}
705
706static PyObject *
707internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
708{
709 PyObject *o;
710 int fd, events = POLLIN | POLLPRI | POLLOUT;
711
712 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
713 return NULL;
714 }
715
716 fd = PyObject_AsFileDescriptor(o);
717 if (fd == -1) return NULL;
718
719 if (remove) {
720 self->fds[self->n_fds].fd = fd;
721 self->fds[self->n_fds].events = POLLREMOVE;
722
723 if (++self->n_fds == self->max_n_fds) {
724 if (devpoll_flush(self))
725 return NULL;
726 }
727 }
728
729 self->fds[self->n_fds].fd = fd;
730 self->fds[self->n_fds].events = events;
731
732 if (++self->n_fds == self->max_n_fds) {
733 if (devpoll_flush(self))
734 return NULL;
735 }
736
737 Py_RETURN_NONE;
738}
739
740PyDoc_STRVAR(devpoll_register_doc,
741"register(fd [, eventmask] ) -> None\n\n\
742Register a file descriptor with the polling object.\n\
743fd -- either an integer, or an object with a fileno() method returning an\n\
744 int.\n\
745events -- an optional bitmask describing the type of events to check for");
746
747static PyObject *
748devpoll_register(devpollObject *self, PyObject *args)
749{
750 return internal_devpoll_register(self, args, 0);
751}
752
753PyDoc_STRVAR(devpoll_modify_doc,
754"modify(fd[, eventmask]) -> None\n\n\
755Modify a possible already registered file descriptor.\n\
756fd -- either an integer, or an object with a fileno() method returning an\n\
757 int.\n\
758events -- an optional bitmask describing the type of events to check for");
759
760static PyObject *
761devpoll_modify(devpollObject *self, PyObject *args)
762{
763 return internal_devpoll_register(self, args, 1);
764}
765
766
767PyDoc_STRVAR(devpoll_unregister_doc,
768"unregister(fd) -> None\n\n\
769Remove a file descriptor being tracked by the polling object.");
770
771static PyObject *
772devpoll_unregister(devpollObject *self, PyObject *o)
773{
774 int fd;
775
776 fd = PyObject_AsFileDescriptor( o );
777 if (fd == -1)
778 return NULL;
779
780 self->fds[self->n_fds].fd = fd;
781 self->fds[self->n_fds].events = POLLREMOVE;
782
783 if (++self->n_fds == self->max_n_fds) {
784 if (devpoll_flush(self))
785 return NULL;
786 }
787
788 Py_RETURN_NONE;
789}
790
791PyDoc_STRVAR(devpoll_poll_doc,
792"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
793Polls the set of registered file descriptors, returning a list containing \n\
794any descriptors that have events or errors to report.");
795
796static PyObject *
797devpoll_poll(devpollObject *self, PyObject *args)
798{
799 struct dvpoll dvp;
800 PyObject *result_list = NULL, *tout = NULL;
801 int poll_result, i;
802 long timeout;
803 PyObject *value, *num1, *num2;
804
805 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
806 return NULL;
807 }
808
809 /* Check values for timeout */
810 if (tout == NULL || tout == Py_None)
811 timeout = -1;
812 else if (!PyNumber_Check(tout)) {
813 PyErr_SetString(PyExc_TypeError,
814 "timeout must be an integer or None");
815 return NULL;
816 }
817 else {
818 tout = PyNumber_Long(tout);
819 if (!tout)
820 return NULL;
821 timeout = PyLong_AsLong(tout);
822 Py_DECREF(tout);
823 if (timeout == -1 && PyErr_Occurred())
824 return NULL;
825 }
826
827 if ((timeout < -1) || (timeout > INT_MAX)) {
828 PyErr_SetString(PyExc_OverflowError,
829 "timeout is out of range");
830 return NULL;
831 }
832
833 if (devpoll_flush(self))
834 return NULL;
835
836 dvp.dp_fds = self->fds;
837 dvp.dp_nfds = self->max_n_fds;
838 dvp.dp_timeout = timeout;
839
840 /* call devpoll() */
841 Py_BEGIN_ALLOW_THREADS
842 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
843 Py_END_ALLOW_THREADS
844
845 if (poll_result < 0) {
846 PyErr_SetFromErrno(PyExc_IOError);
847 return NULL;
848 }
849
850 /* build the result list */
851
852 result_list = PyList_New(poll_result);
853 if (!result_list)
854 return NULL;
855 else {
856 for (i = 0; i < poll_result; i++) {
857 num1 = PyLong_FromLong(self->fds[i].fd);
858 num2 = PyLong_FromLong(self->fds[i].revents);
859 if ((num1 == NULL) || (num2 == NULL)) {
860 Py_XDECREF(num1);
861 Py_XDECREF(num2);
862 goto error;
863 }
864 value = PyTuple_Pack(2, num1, num2);
865 Py_DECREF(num1);
866 Py_DECREF(num2);
867 if (value == NULL)
868 goto error;
869 if ((PyList_SetItem(result_list, i, value)) == -1) {
870 Py_DECREF(value);
871 goto error;
872 }
873 }
874 }
875
876 return result_list;
877
878 error:
879 Py_DECREF(result_list);
880 return NULL;
881}
882
883static PyMethodDef devpoll_methods[] = {
884 {"register", (PyCFunction)devpoll_register,
885 METH_VARARGS, devpoll_register_doc},
886 {"modify", (PyCFunction)devpoll_modify,
887 METH_VARARGS, devpoll_modify_doc},
888 {"unregister", (PyCFunction)devpoll_unregister,
889 METH_O, devpoll_unregister_doc},
890 {"poll", (PyCFunction)devpoll_poll,
891 METH_VARARGS, devpoll_poll_doc},
892 {NULL, NULL} /* sentinel */
893};
894
895static devpollObject *
896newDevPollObject(void)
897{
898 devpollObject *self;
899 int fd_devpoll, limit_result;
900 struct pollfd *fds;
901 struct rlimit limit;
902
903 Py_BEGIN_ALLOW_THREADS
904 /*
905 ** If we try to process more that getrlimit()
906 ** fds, the kernel will give an error, so
907 ** we set the limit here. It is a dynamic
908 ** value, because we can change rlimit() anytime.
909 */
910 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
911 if (limit_result != -1)
912 fd_devpoll = open("/dev/poll", O_RDWR);
913 Py_END_ALLOW_THREADS
914
915 if (limit_result == -1) {
916 PyErr_SetFromErrno(PyExc_OSError);
917 return NULL;
918 }
919 if (fd_devpoll == -1) {
920 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
921 return NULL;
922 }
923
924 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
925 if (fds == NULL) {
926 close(fd_devpoll);
927 PyErr_NoMemory();
928 return NULL;
929 }
930
931 self = PyObject_New(devpollObject, &devpoll_Type);
932 if (self == NULL) {
933 close(fd_devpoll);
934 PyMem_DEL(fds);
935 return NULL;
936 }
937 self->fd_devpoll = fd_devpoll;
938 self->max_n_fds = limit.rlim_cur;
939 self->n_fds = 0;
940 self->fds = fds;
941
942 return self;
943}
944
945static void
946devpoll_dealloc(devpollObject *self)
947{
948 Py_BEGIN_ALLOW_THREADS
949 close(self->fd_devpoll);
950 Py_END_ALLOW_THREADS
951
952 PyMem_DEL(self->fds);
953
954 PyObject_Del(self);
955}
956
957static PyTypeObject devpoll_Type = {
958 /* The ob_type field must be initialized in the module init function
959 * to be portable to Windows without using C++. */
960 PyVarObject_HEAD_INIT(NULL, 0)
961 "select.devpoll", /*tp_name*/
962 sizeof(devpollObject), /*tp_basicsize*/
963 0, /*tp_itemsize*/
964 /* methods */
965 (destructor)devpoll_dealloc, /*tp_dealloc*/
966 0, /*tp_print*/
967 0, /*tp_getattr*/
968 0, /*tp_setattr*/
969 0, /*tp_reserved*/
970 0, /*tp_repr*/
971 0, /*tp_as_number*/
972 0, /*tp_as_sequence*/
973 0, /*tp_as_mapping*/
974 0, /*tp_hash*/
975 0, /*tp_call*/
976 0, /*tp_str*/
977 0, /*tp_getattro*/
978 0, /*tp_setattro*/
979 0, /*tp_as_buffer*/
980 Py_TPFLAGS_DEFAULT, /*tp_flags*/
981 0, /*tp_doc*/
982 0, /*tp_traverse*/
983 0, /*tp_clear*/
984 0, /*tp_richcompare*/
985 0, /*tp_weaklistoffset*/
986 0, /*tp_iter*/
987 0, /*tp_iternext*/
988 devpoll_methods, /*tp_methods*/
989};
990#endif /* HAVE_SYS_DEVPOLL_H */
991
992
993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000994PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000995"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000996unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000997
998static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000999select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001002}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001003
Jesus Cead8b9ae62011-11-14 19:07:41 +01001004#ifdef HAVE_SYS_DEVPOLL_H
1005PyDoc_STRVAR(devpoll_doc,
1006"Returns a polling object, which supports registering and\n\
1007unregistering file descriptors, and then polling them for I/O events.");
1008
1009static PyObject *
1010select_devpoll(PyObject *self, PyObject *unused)
1011{
1012 return (PyObject *)newDevPollObject();
1013}
1014#endif
1015
1016
Thomas Wouters477c8d52006-05-27 19:21:47 +00001017#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019 * On some systems poll() sets errno on invalid file descriptors. We test
1020 * for this at runtime because this bug may be fixed or introduced between
1021 * OS releases.
1022 */
1023static int select_have_broken_poll(void)
1024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 int poll_test;
1026 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 /* Create a file descriptor to make invalid */
1031 if (pipe(filedes) < 0) {
1032 return 1;
1033 }
1034 poll_struct.fd = filedes[0];
1035 close(filedes[0]);
1036 close(filedes[1]);
1037 poll_test = poll(&poll_struct, 1, 0);
1038 if (poll_test < 0) {
1039 return 1;
1040 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1041 return 1;
1042 }
1043 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001044}
1045#endif /* __APPLE__ */
1046
1047#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001048
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001049#ifdef HAVE_EPOLL
1050/* **************************************************************************
1051 * epoll interface for Linux 2.6
1052 *
1053 * Written by Christian Heimes
1054 * Inspired by Twisted's _epoll.pyx and select.poll()
1055 */
1056
1057#ifdef HAVE_SYS_EPOLL_H
1058#include <sys/epoll.h>
1059#endif
1060
1061typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 PyObject_HEAD
1063 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001064} pyEpoll_Object;
1065
1066static PyTypeObject pyEpoll_Type;
1067#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1068
1069static PyObject *
1070pyepoll_err_closed(void)
1071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1073 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001074}
1075
1076static int
1077pyepoll_internal_close(pyEpoll_Object *self)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 int save_errno = 0;
1080 if (self->epfd >= 0) {
1081 int epfd = self->epfd;
1082 self->epfd = -1;
1083 Py_BEGIN_ALLOW_THREADS
1084 if (close(epfd) < 0)
1085 save_errno = errno;
1086 Py_END_ALLOW_THREADS
1087 }
1088 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001089}
1090
1091static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001092newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 assert(type != NULL && type->tp_alloc != NULL);
1097 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1098 if (self == NULL)
1099 return NULL;
1100
1101 if (fd == -1) {
1102 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001103#ifdef HAVE_EPOLL_CREATE1
Benjamin Peterson83251c12011-12-27 16:01:21 -06001104 if (flags)
1105 self->epfd = epoll_create1(flags);
1106 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001107#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001108 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 Py_END_ALLOW_THREADS
1110 }
1111 else {
1112 self->epfd = fd;
1113 }
1114 if (self->epfd < 0) {
1115 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001116 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 return NULL;
1118 }
1119 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001120}
1121
1122
1123static PyObject *
1124pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1125{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001126 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001127 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001128
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001129 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1130 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001132 if (sizehint < 0) {
1133 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1134 return NULL;
1135 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001136
Benjamin Peterson95c16622011-12-27 15:36:32 -06001137 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001138}
1139
1140
1141static void
1142pyepoll_dealloc(pyEpoll_Object *self)
1143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 (void)pyepoll_internal_close(self);
1145 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001146}
1147
1148static PyObject*
1149pyepoll_close(pyEpoll_Object *self)
1150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 errno = pyepoll_internal_close(self);
1152 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001153 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 return NULL;
1155 }
1156 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001157}
1158
1159PyDoc_STRVAR(pyepoll_close_doc,
1160"close() -> None\n\
1161\n\
1162Close the epoll control file descriptor. Further operations on the epoll\n\
1163object will raise an exception.");
1164
1165static PyObject*
1166pyepoll_get_closed(pyEpoll_Object *self)
1167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 if (self->epfd < 0)
1169 Py_RETURN_TRUE;
1170 else
1171 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001172}
1173
1174static PyObject*
1175pyepoll_fileno(pyEpoll_Object *self)
1176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 if (self->epfd < 0)
1178 return pyepoll_err_closed();
1179 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001180}
1181
1182PyDoc_STRVAR(pyepoll_fileno_doc,
1183"fileno() -> int\n\
1184\n\
1185Return the epoll control file descriptor.");
1186
1187static PyObject*
1188pyepoll_fromfd(PyObject *cls, PyObject *args)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1193 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001194
Benjamin Peterson95c16622011-12-27 15:36:32 -06001195 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001196}
1197
1198PyDoc_STRVAR(pyepoll_fromfd_doc,
1199"fromfd(fd) -> epoll\n\
1200\n\
1201Create an epoll object from a given control fd.");
1202
1203static PyObject *
1204pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 struct epoll_event ev;
1207 int result;
1208 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 if (epfd < 0)
1211 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 fd = PyObject_AsFileDescriptor(pfd);
1214 if (fd == -1) {
1215 return NULL;
1216 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 switch(op) {
1219 case EPOLL_CTL_ADD:
1220 case EPOLL_CTL_MOD:
1221 ev.events = events;
1222 ev.data.fd = fd;
1223 Py_BEGIN_ALLOW_THREADS
1224 result = epoll_ctl(epfd, op, fd, &ev);
1225 Py_END_ALLOW_THREADS
1226 break;
1227 case EPOLL_CTL_DEL:
1228 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1229 * operation required a non-NULL pointer in event, even
1230 * though this argument is ignored. */
1231 Py_BEGIN_ALLOW_THREADS
1232 result = epoll_ctl(epfd, op, fd, &ev);
1233 if (errno == EBADF) {
1234 /* fd already closed */
1235 result = 0;
1236 errno = 0;
1237 }
1238 Py_END_ALLOW_THREADS
1239 break;
1240 default:
1241 result = -1;
1242 errno = EINVAL;
1243 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001246 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return NULL;
1248 }
1249 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250}
1251
1252static PyObject *
1253pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 PyObject *pfd;
1256 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1257 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1260 &pfd, &events)) {
1261 return NULL;
1262 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001265}
1266
1267PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001268"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001269\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001270Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001271fd is the target file descriptor of the operation.\n\
1272events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001273is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1274\n\
1275The epoll interface supports all file descriptors that support poll.");
1276
1277static PyObject *
1278pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 PyObject *pfd;
1281 unsigned int events;
1282 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1285 &pfd, &events)) {
1286 return NULL;
1287 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001290}
1291
1292PyDoc_STRVAR(pyepoll_modify_doc,
1293"modify(fd, eventmask) -> None\n\
1294\n\
1295fd is the target file descriptor of the operation\n\
1296events is a bit set composed of the various EPOLL constants");
1297
1298static PyObject *
1299pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 PyObject *pfd;
1302 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1305 &pfd)) {
1306 return NULL;
1307 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001310}
1311
1312PyDoc_STRVAR(pyepoll_unregister_doc,
1313"unregister(fd) -> None\n\
1314\n\
1315fd is the target file descriptor of the operation.");
1316
1317static PyObject *
1318pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 double dtimeout = -1.;
1321 int timeout;
1322 int maxevents = -1;
1323 int nfds, i;
1324 PyObject *elist = NULL, *etuple = NULL;
1325 struct epoll_event *evs = NULL;
1326 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 if (self->epfd < 0)
1329 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1332 &dtimeout, &maxevents)) {
1333 return NULL;
1334 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (dtimeout < 0) {
1337 timeout = -1;
1338 }
1339 else if (dtimeout * 1000.0 > INT_MAX) {
1340 PyErr_SetString(PyExc_OverflowError,
1341 "timeout is too large");
1342 return NULL;
1343 }
1344 else {
1345 timeout = (int)(dtimeout * 1000.0);
1346 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if (maxevents == -1) {
1349 maxevents = FD_SETSIZE-1;
1350 }
1351 else if (maxevents < 1) {
1352 PyErr_Format(PyExc_ValueError,
1353 "maxevents must be greater than 0, got %d",
1354 maxevents);
1355 return NULL;
1356 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 evs = PyMem_New(struct epoll_event, maxevents);
1359 if (evs == NULL) {
1360 Py_DECREF(self);
1361 PyErr_NoMemory();
1362 return NULL;
1363 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 Py_BEGIN_ALLOW_THREADS
1366 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1367 Py_END_ALLOW_THREADS
1368 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001369 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 goto error;
1371 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 elist = PyList_New(nfds);
1374 if (elist == NULL) {
1375 goto error;
1376 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 for (i = 0; i < nfds; i++) {
1379 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1380 if (etuple == NULL) {
1381 Py_CLEAR(elist);
1382 goto error;
1383 }
1384 PyList_SET_ITEM(elist, i, etuple);
1385 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386
Christian Heimesf6cd9672008-03-26 13:45:42 +00001387 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyMem_Free(evs);
1389 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390}
1391
1392PyDoc_STRVAR(pyepoll_poll_doc,
1393"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1394\n\
1395Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1396in seconds (as float). -1 makes poll wait indefinitely.\n\
1397Up to maxevents are returned to the caller.");
1398
1399static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 {"fromfd", (PyCFunction)pyepoll_fromfd,
1401 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1402 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1403 pyepoll_close_doc},
1404 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1405 pyepoll_fileno_doc},
1406 {"modify", (PyCFunction)pyepoll_modify,
1407 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1408 {"register", (PyCFunction)pyepoll_register,
1409 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1410 {"unregister", (PyCFunction)pyepoll_unregister,
1411 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1412 {"poll", (PyCFunction)pyepoll_poll,
1413 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1414 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001415};
1416
1417static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 {"closed", (getter)pyepoll_get_closed, NULL,
1419 "True if the epoll handler is closed"},
1420 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001421};
1422
1423PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001424"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425\n\
1426Returns an epolling object\n\
1427\n\
1428sizehint must be a positive integer or -1 for the default size. The\n\
1429sizehint is used to optimize internal data structures. It doesn't limit\n\
1430the maximum number of monitored events.");
1431
1432static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 PyVarObject_HEAD_INIT(NULL, 0)
1434 "select.epoll", /* tp_name */
1435 sizeof(pyEpoll_Object), /* tp_basicsize */
1436 0, /* tp_itemsize */
1437 (destructor)pyepoll_dealloc, /* tp_dealloc */
1438 0, /* tp_print */
1439 0, /* tp_getattr */
1440 0, /* tp_setattr */
1441 0, /* tp_reserved */
1442 0, /* tp_repr */
1443 0, /* tp_as_number */
1444 0, /* tp_as_sequence */
1445 0, /* tp_as_mapping */
1446 0, /* tp_hash */
1447 0, /* tp_call */
1448 0, /* tp_str */
1449 PyObject_GenericGetAttr, /* tp_getattro */
1450 0, /* tp_setattro */
1451 0, /* tp_as_buffer */
1452 Py_TPFLAGS_DEFAULT, /* tp_flags */
1453 pyepoll_doc, /* tp_doc */
1454 0, /* tp_traverse */
1455 0, /* tp_clear */
1456 0, /* tp_richcompare */
1457 0, /* tp_weaklistoffset */
1458 0, /* tp_iter */
1459 0, /* tp_iternext */
1460 pyepoll_methods, /* tp_methods */
1461 0, /* tp_members */
1462 pyepoll_getsetlist, /* tp_getset */
1463 0, /* tp_base */
1464 0, /* tp_dict */
1465 0, /* tp_descr_get */
1466 0, /* tp_descr_set */
1467 0, /* tp_dictoffset */
1468 0, /* tp_init */
1469 0, /* tp_alloc */
1470 pyepoll_new, /* tp_new */
1471 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001472};
1473
1474#endif /* HAVE_EPOLL */
1475
1476#ifdef HAVE_KQUEUE
1477/* **************************************************************************
1478 * kqueue interface for BSD
1479 *
1480 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1481 * All rights reserved.
1482 *
1483 * Redistribution and use in source and binary forms, with or without
1484 * modification, are permitted provided that the following conditions
1485 * are met:
1486 * 1. Redistributions of source code must retain the above copyright
1487 * notice, this list of conditions and the following disclaimer.
1488 * 2. Redistributions in binary form must reproduce the above copyright
1489 * notice, this list of conditions and the following disclaimer in the
1490 * documentation and/or other materials provided with the distribution.
1491 *
1492 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1493 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1494 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1495 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1496 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1497 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1498 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1499 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1500 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1501 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1502 * SUCH DAMAGE.
1503 */
1504
1505#ifdef HAVE_SYS_EVENT_H
1506#include <sys/event.h>
1507#endif
1508
1509PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001510"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511\n\
1512This object is the equivalent of the struct kevent for the C API.\n\
1513\n\
1514See the kqueue manpage for more detailed information about the meaning\n\
1515of the arguments.\n\
1516\n\
1517One minor note: while you might hope that udata could store a\n\
1518reference to a python object, it cannot, because it is impossible to\n\
1519keep a proper reference count of the object once it's passed into the\n\
1520kernel. Therefore, I have restricted it to only storing an integer. I\n\
1521recommend ignoring it and simply using the 'ident' field to key off\n\
1522of. You could also set up a dictionary on the python side to store a\n\
1523udata->object mapping.");
1524
1525typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 PyObject_HEAD
1527 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001528} kqueue_event_Object;
1529
1530static PyTypeObject kqueue_event_Type;
1531
1532#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1533
1534typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 PyObject_HEAD
1536 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001537} kqueue_queue_Object;
1538
1539static PyTypeObject kqueue_queue_Type;
1540
1541#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1542
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001543#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1544# error uintptr_t does not match void *!
1545#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1546# define T_UINTPTRT T_ULONGLONG
1547# define T_INTPTRT T_LONGLONG
1548# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1549# define UINTPTRT_FMT_UNIT "K"
1550# define INTPTRT_FMT_UNIT "L"
1551#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1552# define T_UINTPTRT T_ULONG
1553# define T_INTPTRT T_LONG
1554# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1555# define UINTPTRT_FMT_UNIT "k"
1556# define INTPTRT_FMT_UNIT "l"
1557#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1558# define T_UINTPTRT T_UINT
1559# define T_INTPTRT T_INT
1560# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1561# define UINTPTRT_FMT_UNIT "I"
1562# define INTPTRT_FMT_UNIT "i"
1563#else
1564# error uintptr_t does not match int, long, or long long!
1565#endif
1566
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001567/* Unfortunately, we can't store python objects in udata, because
1568 * kevents in the kernel can be removed without warning, which would
1569 * forever lose the refcount on the object stored with it.
1570 */
1571
1572#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1573static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1575 {"filter", T_SHORT, KQ_OFF(e.filter)},
1576 {"flags", T_USHORT, KQ_OFF(e.flags)},
1577 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1578 {"data", T_INTPTRT, KQ_OFF(e.data)},
1579 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1580 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001581};
1582#undef KQ_OFF
1583
1584static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001585
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001586kqueue_event_repr(kqueue_event_Object *s)
1587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 char buf[1024];
1589 PyOS_snprintf(
1590 buf, sizeof(buf),
1591 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1592 "data=0x%zd udata=%p>",
1593 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1594 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1595 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596}
1597
1598static int
1599kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 PyObject *pfd;
1602 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1603 "data", "udata", NULL};
1604 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1609 &pfd, &(self->e.filter), &(self->e.flags),
1610 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1611 return -1;
1612 }
1613
1614 if (PyLong_Check(pfd)) {
1615 self->e.ident = PyLong_AsUintptr_t(pfd);
1616 }
1617 else {
1618 self->e.ident = PyObject_AsFileDescriptor(pfd);
1619 }
1620 if (PyErr_Occurred()) {
1621 return -1;
1622 }
1623 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001624}
1625
1626static PyObject *
1627kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 if (!kqueue_event_Check(o)) {
1633 if (op == Py_EQ || op == Py_NE) {
1634 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1635 Py_INCREF(res);
1636 return res;
1637 }
1638 PyErr_Format(PyExc_TypeError,
1639 "can't compare %.200s to %.200s",
1640 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1641 return NULL;
1642 }
1643 if (((result = s->e.ident - o->e.ident) == 0) &&
1644 ((result = s->e.filter - o->e.filter) == 0) &&
1645 ((result = s->e.flags - o->e.flags) == 0) &&
1646 ((result = s->e.fflags - o->e.fflags) == 0) &&
1647 ((result = s->e.data - o->e.data) == 0) &&
1648 ((result = s->e.udata - o->e.udata) == 0)
1649 ) {
1650 result = 0;
1651 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 switch (op) {
1654 case Py_EQ:
1655 result = (result == 0);
1656 break;
1657 case Py_NE:
1658 result = (result != 0);
1659 break;
1660 case Py_LE:
1661 result = (result <= 0);
1662 break;
1663 case Py_GE:
1664 result = (result >= 0);
1665 break;
1666 case Py_LT:
1667 result = (result < 0);
1668 break;
1669 case Py_GT:
1670 result = (result > 0);
1671 break;
1672 }
1673 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001674}
1675
1676static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 PyVarObject_HEAD_INIT(NULL, 0)
1678 "select.kevent", /* tp_name */
1679 sizeof(kqueue_event_Object), /* tp_basicsize */
1680 0, /* tp_itemsize */
1681 0, /* tp_dealloc */
1682 0, /* tp_print */
1683 0, /* tp_getattr */
1684 0, /* tp_setattr */
1685 0, /* tp_reserved */
1686 (reprfunc)kqueue_event_repr, /* tp_repr */
1687 0, /* tp_as_number */
1688 0, /* tp_as_sequence */
1689 0, /* tp_as_mapping */
1690 0, /* tp_hash */
1691 0, /* tp_call */
1692 0, /* tp_str */
1693 0, /* tp_getattro */
1694 0, /* tp_setattro */
1695 0, /* tp_as_buffer */
1696 Py_TPFLAGS_DEFAULT, /* tp_flags */
1697 kqueue_event_doc, /* tp_doc */
1698 0, /* tp_traverse */
1699 0, /* tp_clear */
1700 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1701 0, /* tp_weaklistoffset */
1702 0, /* tp_iter */
1703 0, /* tp_iternext */
1704 0, /* tp_methods */
1705 kqueue_event_members, /* tp_members */
1706 0, /* tp_getset */
1707 0, /* tp_base */
1708 0, /* tp_dict */
1709 0, /* tp_descr_get */
1710 0, /* tp_descr_set */
1711 0, /* tp_dictoffset */
1712 (initproc)kqueue_event_init, /* tp_init */
1713 0, /* tp_alloc */
1714 0, /* tp_new */
1715 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001716};
1717
1718static PyObject *
1719kqueue_queue_err_closed(void)
1720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1722 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001723}
1724
1725static int
1726kqueue_queue_internal_close(kqueue_queue_Object *self)
1727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 int save_errno = 0;
1729 if (self->kqfd >= 0) {
1730 int kqfd = self->kqfd;
1731 self->kqfd = -1;
1732 Py_BEGIN_ALLOW_THREADS
1733 if (close(kqfd) < 0)
1734 save_errno = errno;
1735 Py_END_ALLOW_THREADS
1736 }
1737 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001738}
1739
1740static PyObject *
1741newKqueue_Object(PyTypeObject *type, SOCKET fd)
1742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 kqueue_queue_Object *self;
1744 assert(type != NULL && type->tp_alloc != NULL);
1745 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1746 if (self == NULL) {
1747 return NULL;
1748 }
1749
1750 if (fd == -1) {
1751 Py_BEGIN_ALLOW_THREADS
1752 self->kqfd = kqueue();
1753 Py_END_ALLOW_THREADS
1754 }
1755 else {
1756 self->kqfd = fd;
1757 }
1758 if (self->kqfd < 0) {
1759 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001760 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 return NULL;
1762 }
1763 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001764}
1765
1766static PyObject *
1767kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1768{
1769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 if ((args != NULL && PyObject_Size(args)) ||
1771 (kwds != NULL && PyObject_Size(kwds))) {
1772 PyErr_SetString(PyExc_ValueError,
1773 "select.kqueue doesn't accept arguments");
1774 return NULL;
1775 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001778}
1779
1780static void
1781kqueue_queue_dealloc(kqueue_queue_Object *self)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 kqueue_queue_internal_close(self);
1784 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001785}
1786
1787static PyObject*
1788kqueue_queue_close(kqueue_queue_Object *self)
1789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 errno = kqueue_queue_internal_close(self);
1791 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001792 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 return NULL;
1794 }
1795 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001796}
1797
1798PyDoc_STRVAR(kqueue_queue_close_doc,
1799"close() -> None\n\
1800\n\
1801Close the kqueue control file descriptor. Further operations on the kqueue\n\
1802object will raise an exception.");
1803
1804static PyObject*
1805kqueue_queue_get_closed(kqueue_queue_Object *self)
1806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 if (self->kqfd < 0)
1808 Py_RETURN_TRUE;
1809 else
1810 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001811}
1812
1813static PyObject*
1814kqueue_queue_fileno(kqueue_queue_Object *self)
1815{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 if (self->kqfd < 0)
1817 return kqueue_queue_err_closed();
1818 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001819}
1820
1821PyDoc_STRVAR(kqueue_queue_fileno_doc,
1822"fileno() -> int\n\
1823\n\
1824Return the kqueue control file descriptor.");
1825
1826static PyObject*
1827kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1832 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001835}
1836
1837PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1838"fromfd(fd) -> kqueue\n\
1839\n\
1840Create a kqueue object from a given control fd.");
1841
1842static PyObject *
1843kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 int nevents = 0;
1846 int gotevents = 0;
1847 int nchanges = 0;
1848 int i = 0;
1849 PyObject *otimeout = NULL;
1850 PyObject *ch = NULL;
1851 PyObject *it = NULL, *ei = NULL;
1852 PyObject *result = NULL;
1853 struct kevent *evl = NULL;
1854 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01001855 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 if (self->kqfd < 0)
1859 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1862 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (nevents < 0) {
1865 PyErr_Format(PyExc_ValueError,
1866 "Length of eventlist must be 0 or positive, got %d",
1867 nevents);
1868 return NULL;
1869 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 if (otimeout == Py_None || otimeout == NULL) {
1872 ptimeoutspec = NULL;
1873 }
1874 else if (PyNumber_Check(otimeout)) {
Victor Stinner5d272cc2012-03-13 13:35:55 +01001875 if (_PyTime_ObjectToTimespec(otimeout,
1876 &timeout.tv_sec, &timeout.tv_nsec) == -1)
1877 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001878
Victor Stinner5d272cc2012-03-13 13:35:55 +01001879 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 PyErr_SetString(PyExc_ValueError,
1881 "timeout must be positive or None");
1882 return NULL;
1883 }
Victor Stinnerd528b012012-03-13 16:25:35 +01001884 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 }
1886 else {
1887 PyErr_Format(PyExc_TypeError,
1888 "timeout argument must be an number "
1889 "or None, got %.200s",
1890 Py_TYPE(otimeout)->tp_name);
1891 return NULL;
1892 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 if (ch != NULL && ch != Py_None) {
1895 it = PyObject_GetIter(ch);
1896 if (it == NULL) {
1897 PyErr_SetString(PyExc_TypeError,
1898 "changelist is not iterable");
1899 return NULL;
1900 }
1901 nchanges = PyObject_Size(ch);
1902 if (nchanges < 0) {
1903 goto error;
1904 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 chl = PyMem_New(struct kevent, nchanges);
1907 if (chl == NULL) {
1908 PyErr_NoMemory();
1909 goto error;
1910 }
1911 i = 0;
1912 while ((ei = PyIter_Next(it)) != NULL) {
1913 if (!kqueue_event_Check(ei)) {
1914 Py_DECREF(ei);
1915 PyErr_SetString(PyExc_TypeError,
1916 "changelist must be an iterable of "
1917 "select.kevent objects");
1918 goto error;
1919 } else {
1920 chl[i++] = ((kqueue_event_Object *)ei)->e;
1921 }
1922 Py_DECREF(ei);
1923 }
1924 }
1925 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 /* event list */
1928 if (nevents) {
1929 evl = PyMem_New(struct kevent, nevents);
1930 if (evl == NULL) {
1931 PyErr_NoMemory();
1932 goto error;
1933 }
1934 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 Py_BEGIN_ALLOW_THREADS
1937 gotevents = kevent(self->kqfd, chl, nchanges,
1938 evl, nevents, ptimeoutspec);
1939 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 if (gotevents == -1) {
1942 PyErr_SetFromErrno(PyExc_OSError);
1943 goto error;
1944 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 result = PyList_New(gotevents);
1947 if (result == NULL) {
1948 goto error;
1949 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 for (i = 0; i < gotevents; i++) {
1952 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1955 if (ch == NULL) {
1956 goto error;
1957 }
1958 ch->e = evl[i];
1959 PyList_SET_ITEM(result, i, (PyObject *)ch);
1960 }
1961 PyMem_Free(chl);
1962 PyMem_Free(evl);
1963 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001964
1965 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 PyMem_Free(chl);
1967 PyMem_Free(evl);
1968 Py_XDECREF(result);
1969 Py_XDECREF(it);
1970 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001971}
1972
1973PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001974"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001975\n\
1976Calls the kernel kevent function.\n\
1977- changelist must be a list of kevent objects describing the changes\n\
1978 to be made to the kernel's watch list or None.\n\
1979- max_events lets you specify the maximum number of events that the\n\
1980 kernel will return.\n\
1981- timeout is the maximum time to wait in seconds, or else None,\n\
1982 to wait forever. timeout accepts floats for smaller timeouts, too.");
1983
1984
1985static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1987 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1988 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1989 kqueue_queue_close_doc},
1990 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1991 kqueue_queue_fileno_doc},
1992 {"control", (PyCFunction)kqueue_queue_control,
1993 METH_VARARGS , kqueue_queue_control_doc},
1994 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001995};
1996
1997static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 {"closed", (getter)kqueue_queue_get_closed, NULL,
1999 "True if the kqueue handler is closed"},
2000 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002001};
2002
2003PyDoc_STRVAR(kqueue_queue_doc,
2004"Kqueue syscall wrapper.\n\
2005\n\
2006For example, to start watching a socket for input:\n\
2007>>> kq = kqueue()\n\
2008>>> sock = socket()\n\
2009>>> sock.connect((host, port))\n\
2010>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2011\n\
2012To wait one second for it to become writeable:\n\
2013>>> kq.control(None, 1, 1000)\n\
2014\n\
2015To stop listening:\n\
2016>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2017
2018static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 PyVarObject_HEAD_INIT(NULL, 0)
2020 "select.kqueue", /* tp_name */
2021 sizeof(kqueue_queue_Object), /* tp_basicsize */
2022 0, /* tp_itemsize */
2023 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2024 0, /* tp_print */
2025 0, /* tp_getattr */
2026 0, /* tp_setattr */
2027 0, /* tp_reserved */
2028 0, /* tp_repr */
2029 0, /* tp_as_number */
2030 0, /* tp_as_sequence */
2031 0, /* tp_as_mapping */
2032 0, /* tp_hash */
2033 0, /* tp_call */
2034 0, /* tp_str */
2035 0, /* tp_getattro */
2036 0, /* tp_setattro */
2037 0, /* tp_as_buffer */
2038 Py_TPFLAGS_DEFAULT, /* tp_flags */
2039 kqueue_queue_doc, /* tp_doc */
2040 0, /* tp_traverse */
2041 0, /* tp_clear */
2042 0, /* tp_richcompare */
2043 0, /* tp_weaklistoffset */
2044 0, /* tp_iter */
2045 0, /* tp_iternext */
2046 kqueue_queue_methods, /* tp_methods */
2047 0, /* tp_members */
2048 kqueue_queue_getsetlist, /* tp_getset */
2049 0, /* tp_base */
2050 0, /* tp_dict */
2051 0, /* tp_descr_get */
2052 0, /* tp_descr_set */
2053 0, /* tp_dictoffset */
2054 0, /* tp_init */
2055 0, /* tp_alloc */
2056 kqueue_queue_new, /* tp_new */
2057 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002058};
2059
2060#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002061
2062
2063
2064
2065
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002066/* ************************************************************************ */
2067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002069"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2070\n\
2071Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002072The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002073rlist -- wait until ready for reading\n\
2074wlist -- wait until ready for writing\n\
2075xlist -- wait for an ``exceptional condition''\n\
2076If only one kind of condition is required, pass [] for the other lists.\n\
2077A file descriptor is either a socket or file object, or a small integer\n\
2078gotten from a fileno() method call on one of those.\n\
2079\n\
2080The optional 4th argument specifies a timeout in seconds; it may be\n\
2081a floating point number to specify fractions of seconds. If it is absent\n\
2082or None, the call will never time out.\n\
2083\n\
2084The return value is a tuple of three lists corresponding to the first three\n\
2085arguments; each contains the subset of the corresponding file descriptors\n\
2086that are ready.\n\
2087\n\
2088*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002089On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002090descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002091
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002092static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002094#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002096#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002097#ifdef HAVE_SYS_DEVPOLL_H
2098 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2099#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002101};
2102
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002103PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002104"This module supports asynchronous I/O on multiple file descriptors.\n\
2105\n\
2106*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002107On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002108
Martin v. Löwis1a214512008-06-11 05:26:20 +00002109
2110static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 PyModuleDef_HEAD_INIT,
2112 "select",
2113 module_doc,
2114 -1,
2115 select_methods,
2116 NULL,
2117 NULL,
2118 NULL,
2119 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002120};
2121
Jesus Cead8b9ae62011-11-14 19:07:41 +01002122
2123
2124
Mark Hammond62b1ab12002-07-23 06:31:15 +00002125PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002126PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 PyObject *m;
2129 m = PyModule_Create(&selectmodule);
2130 if (m == NULL)
2131 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002132
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002133 Py_INCREF(PyExc_OSError);
2134 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002135
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002136#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002137#ifdef HAVE_BROKEN_PIPE_BUF
2138#undef PIPE_BUF
2139#define PIPE_BUF 512
2140#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002142#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002143
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002144#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002145#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 if (select_have_broken_poll()) {
2147 if (PyObject_DelAttrString(m, "poll") == -1) {
2148 PyErr_Clear();
2149 }
2150 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002151#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002153#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 if (PyType_Ready(&poll_Type) < 0)
2155 return NULL;
2156 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2157 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2158 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2159 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2160 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2161 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002162
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002163#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002165#endif
2166#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002168#endif
2169#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002171#endif
2172#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002174#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002175#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002177#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002179#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002180
Jesus Cead8b9ae62011-11-14 19:07:41 +01002181#ifdef HAVE_SYS_DEVPOLL_H
2182 if (PyType_Ready(&devpoll_Type) < 0)
2183 return NULL;
2184#endif
2185
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002186#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2188 if (PyType_Ready(&pyEpoll_Type) < 0)
2189 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 Py_INCREF(&pyEpoll_Type);
2192 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2195 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2196 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2197 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2198 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2199 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002200#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002201 /* Kernel 2.6.2+ */
2202 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002203#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2205 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2206 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2207 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2208 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2209 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002210
Benjamin Peterson95c16622011-12-27 15:36:32 -06002211#ifdef EPOLL_CLOEXEC
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002212 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002213#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002214#endif /* HAVE_EPOLL */
2215
2216#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 kqueue_event_Type.tp_new = PyType_GenericNew;
2218 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2219 if(PyType_Ready(&kqueue_event_Type) < 0)
2220 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 Py_INCREF(&kqueue_event_Type);
2223 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2226 if(PyType_Ready(&kqueue_queue_Type) < 0)
2227 return NULL;
2228 Py_INCREF(&kqueue_queue_Type);
2229 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2230
2231 /* event filters */
2232 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2233 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2234 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2235 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2236 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002237#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002239#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2241 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 /* event flags */
2244 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2245 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2246 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2247 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2248 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2249 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2252 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2255 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 /* READ WRITE filter flag */
2258 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 /* VNODE filter flags */
2261 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2262 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2263 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2264 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2265 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2266 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2267 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 /* PROC filter flags */
2270 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2272 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2273 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2274 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2277 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2278 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2279
2280 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002281#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2283 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2284 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002285#endif
2286
2287#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002289}