blob: b95b2cedc175cab4ebbe09bfd5e15e12d1c4829a [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 Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Christian Heimes0e9ab5f2008-03-21 23:49:44 +000010#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000011
Ronald Oussoren32fd16e2006-04-23 12:36:23 +000012#ifdef __APPLE__
13 /* Perform runtime testing for a broken poll on OSX to make it easier
14 * to use the same binary on multiple releases of the OS.
15 */
16#undef HAVE_BROKEN_POLL
17#endif
18
Tim Petersd92dfe02000-12-12 01:18:41 +000019/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
20 64 is too small (too many people have bumped into that limit).
21 Here we boost it.
22 Users who want even more than the boosted limit should #define
23 FD_SETSIZE higher before this; e.g., via compiler /D switch.
24*/
25#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
26#define FD_SETSIZE 512
Antoine Pitrouc83ea132010-05-09 14:46:46 +000027#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000028
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000030#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000031#elif defined(HAVE_SYS_POLL_H)
32#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000033#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000034
Guido van Rossum37273171996-12-09 18:47:43 +000035#ifdef __sgi
36/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000037extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000038#endif
39
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000040#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000042#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000044#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#include <sys/time.h>
46#include <utils.h>
47#endif
48
Guido van Rossum6f489d91996-06-28 20:15:15 +000049#ifdef MS_WINDOWS
Kristján Valur Jónssonf6f3c4a2010-11-03 13:27:33 +000050# include <winsock2.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051#else
Neal Norwitz2a30cd02006-07-10 01:18:57 +000052# define SOCKET int
53# ifdef __BEOS__
54# include <net/socket.h>
55# elif defined(__VMS)
56# 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 Warsawe4ac0aa1996-12-12 00:04:35 +000060static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000061
Barry Warsawc1cb3601996-12-12 22:16:21 +000062/* list of Python objects and their file descriptor */
63typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000064 PyObject *obj; /* owned reference */
65 SOCKET fd;
66 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000067} pylist;
68
Barry Warsawc1cb3601996-12-12 22:16:21 +000069static void
Tim Peters4b046c22001-08-16 21:59:46 +000070reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000071{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000072 int i;
73 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
74 Py_XDECREF(fd2obj[i].obj);
75 fd2obj[i].obj = NULL;
76 }
77 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000078}
79
80
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000081/* returns -1 and sets the Python exception if an error occurred, otherwise
82 returns a number >= 0
83*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000084static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000085seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000086{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000087 int i;
88 int max = -1;
89 int index = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000090 PyObject* fast_seq = NULL;
91 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000092
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
94 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000095
Antoine Pitrouc83ea132010-05-09 14:46:46 +000096 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
97 if (!fast_seq)
98 return -1;
99
Antoine Pitrou0552fc22012-11-01 20:13:54 +0100100 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000105 return -1;
106
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000112 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#else /* !_MSC_VER */
Charles-François Natalifda7b372011-08-28 16:22:33 +0200114 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000148 int i, j, count=0;
149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000170 i++;
171 }
172 }
173 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000188 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000189#else /* !SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +0000200 PyObject *ifdlist, *ofdlist, *efdlist;
201 PyObject *ret = NULL;
202 PyObject *tout = Py_None;
203 fd_set ifdset, ofdset, efdset;
204 double timeout;
205 struct timeval tv, *tvp;
206 long seconds;
207 int imax, omax, emax, max;
208 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000209
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000210 /* convert arguments */
211 if (!PyArg_UnpackTuple(args, "select", 3, 4,
212 &ifdlist, &ofdlist, &efdlist, &tout))
213 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000214
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 if (tout == Py_None)
216 tvp = (struct timeval *)0;
217 else if (!PyNumber_Check(tout)) {
218 PyErr_SetString(PyExc_TypeError,
219 "timeout must be a float or None");
220 return NULL;
221 }
222 else {
223 timeout = PyFloat_AsDouble(tout);
224 if (timeout == -1 && PyErr_Occurred())
225 return NULL;
226 if (timeout > (double)LONG_MAX) {
227 PyErr_SetString(PyExc_OverflowError,
228 "timeout period too long");
229 return NULL;
230 }
231 seconds = (long)timeout;
232 timeout = timeout - (double)seconds;
233 tv.tv_sec = seconds;
234 tv.tv_usec = (long)(timeout * 1E6);
235 tvp = &tv;
236 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000237
Guido van Rossumed233a51992-06-23 09:07:03 +0000238
Barry Warsawb44740f2001-08-16 16:52:59 +0000239#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000240 /* Allocate memory for the lists */
241 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
242 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
243 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
244 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
245 if (rfd2obj) PyMem_DEL(rfd2obj);
246 if (wfd2obj) PyMem_DEL(wfd2obj);
247 if (efd2obj) PyMem_DEL(efd2obj);
248 return PyErr_NoMemory();
249 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000251 /* Convert sequences to fd_sets, and get maximum fd number
252 * propagates the Python exception set in seq2set()
253 */
254 rfd2obj[0].sentinel = -1;
255 wfd2obj[0].sentinel = -1;
256 efd2obj[0].sentinel = -1;
257 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
258 goto finally;
259 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
260 goto finally;
261 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
262 goto finally;
263 max = imax;
264 if (omax > max) max = omax;
265 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000266
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000267 Py_BEGIN_ALLOW_THREADS
268 n = select(max, &ifdset, &ofdset, &efdset, tvp);
269 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000270
Thomas Heller106f4c72002-09-24 16:51:00 +0000271#ifdef MS_WINDOWS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 if (n == SOCKET_ERROR) {
273 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
274 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000275#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 if (n < 0) {
277 PyErr_SetFromErrno(SelectError);
278 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000279#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000280 else {
281 /* any of these three calls can raise an exception. it's more
282 convenient to test for this after all three calls... but
283 is that acceptable?
284 */
285 ifdlist = set2list(&ifdset, rfd2obj);
286 ofdlist = set2list(&ofdset, wfd2obj);
287 efdlist = set2list(&efdset, efd2obj);
288 if (PyErr_Occurred())
289 ret = NULL;
290 else
291 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000292
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293 Py_DECREF(ifdlist);
294 Py_DECREF(ofdlist);
295 Py_DECREF(efdlist);
296 }
297
Barry Warsawc1cb3601996-12-12 22:16:21 +0000298 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299 reap_obj(rfd2obj);
300 reap_obj(wfd2obj);
301 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000302#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000303 PyMem_DEL(rfd2obj);
304 PyMem_DEL(wfd2obj);
305 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000306#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000307 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000308}
309
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000310#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000311/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000312 * poll() support
313 */
314
315typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000316 PyObject_HEAD
317 PyObject *dict;
318 int ufd_uptodate;
319 int ufd_len;
320 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000321} pollObject;
322
Jeremy Hylton938ace62002-07-17 16:30:39 +0000323static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000324
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000325/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000326 contained within a pollObject. Return 1 on success, 0 on an error.
327*/
328
329static int
330update_ufd_array(pollObject *self)
331{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000332 Py_ssize_t i, pos;
333 PyObject *key, *value;
334 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000336 self->ufd_len = PyDict_Size(self->dict);
337 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
338 if (self->ufds == NULL) {
339 self->ufds = old_ufds;
340 PyErr_NoMemory();
341 return 0;
342 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000343
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000344 i = pos = 0;
345 while (PyDict_Next(self->dict, &pos, &key, &value)) {
346 self->ufds[i].fd = PyInt_AsLong(key);
347 self->ufds[i].events = (short)PyInt_AsLong(value);
348 i++;
349 }
350 self->ufd_uptodate = 1;
351 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000352}
353
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000354PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000355"register(fd [, eventmask] ) -> None\n\n\
356Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000357fd -- either an integer, or an object with a fileno() method returning an\n\
358 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000359events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000360
361static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000362poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000364 PyObject *o, *key, *value;
365 int fd, events = POLLIN | POLLPRI | POLLOUT;
366 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000368 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
369 return NULL;
370 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000372 fd = PyObject_AsFileDescriptor(o);
373 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000374
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000375 /* Add entry to the internal dictionary: the key is the
376 file descriptor, and the value is the event mask. */
377 key = PyInt_FromLong(fd);
378 if (key == NULL)
379 return NULL;
380 value = PyInt_FromLong(events);
381 if (value == NULL) {
382 Py_DECREF(key);
383 return NULL;
384 }
385 err = PyDict_SetItem(self->dict, key, value);
386 Py_DECREF(key);
387 Py_DECREF(value);
388 if (err < 0)
389 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000390
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000391 self->ufd_uptodate = 0;
392
393 Py_INCREF(Py_None);
394 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000395}
396
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000397PyDoc_STRVAR(poll_modify_doc,
398"modify(fd, eventmask) -> None\n\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000399Modify an already registered file descriptor.\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000400fd -- either an integer, or an object with a fileno() method returning an\n\
401 int.\n\
402events -- an optional bitmask describing the type of events to check for");
403
404static PyObject *
405poll_modify(pollObject *self, PyObject *args)
406{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000407 PyObject *o, *key, *value;
408 int fd, events;
409 int err;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000410
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000411 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
412 return NULL;
413 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000414
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000415 fd = PyObject_AsFileDescriptor(o);
416 if (fd == -1) return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000417
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000418 /* Modify registered fd */
419 key = PyInt_FromLong(fd);
420 if (key == NULL)
421 return NULL;
422 if (PyDict_GetItem(self->dict, key) == NULL) {
423 errno = ENOENT;
424 PyErr_SetFromErrno(PyExc_IOError);
425 return NULL;
426 }
427 value = PyInt_FromLong(events);
428 if (value == NULL) {
429 Py_DECREF(key);
430 return NULL;
431 }
432 err = PyDict_SetItem(self->dict, key, value);
433 Py_DECREF(key);
434 Py_DECREF(value);
435 if (err < 0)
436 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000437
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000438 self->ufd_uptodate = 0;
439
440 Py_INCREF(Py_None);
441 return Py_None;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000442}
443
444
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000445PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000446"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000447Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448
449static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000450poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000451{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000452 PyObject *key;
453 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000454
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000455 fd = PyObject_AsFileDescriptor( o );
456 if (fd == -1)
457 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000459 /* Check whether the fd is already in the array */
460 key = PyInt_FromLong(fd);
461 if (key == NULL)
462 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000464 if (PyDict_DelItem(self->dict, key) == -1) {
465 Py_DECREF(key);
466 /* This will simply raise the KeyError set by PyDict_DelItem
467 if the file descriptor isn't registered. */
468 return NULL;
469 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000471 Py_DECREF(key);
472 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000474 Py_INCREF(Py_None);
475 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000476}
477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000478PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000479"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
480Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000481any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000482
483static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000484poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000485{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000486 PyObject *result_list = NULL, *tout = NULL;
487 int timeout = 0, poll_result, i, j;
488 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000490 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
491 return NULL;
492 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000494 /* Check values for timeout */
495 if (tout == NULL || tout == Py_None)
496 timeout = -1;
497 else if (!PyNumber_Check(tout)) {
498 PyErr_SetString(PyExc_TypeError,
499 "timeout must be an integer or None");
500 return NULL;
501 }
502 else {
503 tout = PyNumber_Int(tout);
504 if (!tout)
505 return NULL;
506 timeout = PyInt_AsLong(tout);
507 Py_DECREF(tout);
508 if (timeout == -1 && PyErr_Occurred())
509 return NULL;
510 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000511
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000512 /* Ensure the ufd array is up to date */
513 if (!self->ufd_uptodate)
514 if (update_ufd_array(self) == 0)
515 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000516
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000517 /* call poll() */
518 Py_BEGIN_ALLOW_THREADS
519 poll_result = poll(self->ufds, self->ufd_len, timeout);
520 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000522 if (poll_result < 0) {
523 PyErr_SetFromErrno(SelectError);
524 return NULL;
525 }
526
527 /* build the result list */
528
529 result_list = PyList_New(poll_result);
530 if (!result_list)
531 return NULL;
532 else {
533 for (i = 0, j = 0; j < poll_result; j++) {
534 /* skip to the next fired descriptor */
535 while (!self->ufds[i].revents) {
536 i++;
537 }
538 /* if we hit a NULL return, set value to NULL
539 and break out of loop; code at end will
540 clean up result_list */
541 value = PyTuple_New(2);
542 if (value == NULL)
543 goto error;
544 num = PyInt_FromLong(self->ufds[i].fd);
545 if (num == NULL) {
546 Py_DECREF(value);
547 goto error;
548 }
549 PyTuple_SET_ITEM(value, 0, num);
550
551 /* The &0xffff is a workaround for AIX. 'revents'
552 is a 16-bit short, and IBM assigned POLLNVAL
553 to be 0x8000, so the conversion to int results
554 in a negative number. See SF bug #923315. */
555 num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
556 if (num == NULL) {
557 Py_DECREF(value);
558 goto error;
559 }
560 PyTuple_SET_ITEM(value, 1, num);
561 if ((PyList_SetItem(result_list, j, value)) == -1) {
562 Py_DECREF(value);
563 goto error;
564 }
565 i++;
566 }
567 }
568 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000569
570 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000571 Py_DECREF(result_list);
572 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000573}
574
575static PyMethodDef poll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000576 {"register", (PyCFunction)poll_register,
577 METH_VARARGS, poll_register_doc},
578 {"modify", (PyCFunction)poll_modify,
579 METH_VARARGS, poll_modify_doc},
580 {"unregister", (PyCFunction)poll_unregister,
581 METH_O, poll_unregister_doc},
582 {"poll", (PyCFunction)poll_poll,
583 METH_VARARGS, poll_poll_doc},
584 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000585};
586
587static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000588newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000590 pollObject *self;
591 self = PyObject_New(pollObject, &poll_Type);
592 if (self == NULL)
593 return NULL;
594 /* ufd_uptodate is a Boolean, denoting whether the
595 array pointed to by ufds matches the contents of the dictionary. */
596 self->ufd_uptodate = 0;
597 self->ufds = NULL;
598 self->dict = PyDict_New();
599 if (self->dict == NULL) {
600 Py_DECREF(self);
601 return NULL;
602 }
603 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604}
605
606static void
607poll_dealloc(pollObject *self)
608{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000609 if (self->ufds != NULL)
610 PyMem_DEL(self->ufds);
611 Py_XDECREF(self->dict);
612 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000613}
614
615static PyObject *
616poll_getattr(pollObject *self, char *name)
617{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000618 return Py_FindMethod(poll_methods, (PyObject *)self, name);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000619}
620
Tim Peters0c322792002-07-17 16:49:03 +0000621static PyTypeObject poll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000622 /* The ob_type field must be initialized in the module init function
623 * to be portable to Windows without using C++. */
624 PyVarObject_HEAD_INIT(NULL, 0)
625 "select.poll", /*tp_name*/
626 sizeof(pollObject), /*tp_basicsize*/
627 0, /*tp_itemsize*/
628 /* methods */
629 (destructor)poll_dealloc, /*tp_dealloc*/
630 0, /*tp_print*/
631 (getattrfunc)poll_getattr, /*tp_getattr*/
632 0, /*tp_setattr*/
633 0, /*tp_compare*/
634 0, /*tp_repr*/
635 0, /*tp_as_number*/
636 0, /*tp_as_sequence*/
637 0, /*tp_as_mapping*/
638 0, /*tp_hash*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000639};
640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000641PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000642"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000643unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000644
645static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +0000646select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000647{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000648 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000649}
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000650
651#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000652/*
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000653 * On some systems poll() sets errno on invalid file descriptors. We test
654 * for this at runtime because this bug may be fixed or introduced between
655 * OS releases.
656 */
657static int select_have_broken_poll(void)
658{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000659 int poll_test;
660 int filedes[2];
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000661
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000662 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000663
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000664 /* Create a file descriptor to make invalid */
665 if (pipe(filedes) < 0) {
666 return 1;
667 }
668 poll_struct.fd = filedes[0];
669 close(filedes[0]);
670 close(filedes[1]);
671 poll_test = poll(&poll_struct, 1, 0);
672 if (poll_test < 0) {
673 return 1;
674 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
675 return 1;
676 }
677 return 0;
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000678}
679#endif /* __APPLE__ */
680
681#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000682
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000683#ifdef HAVE_EPOLL
684/* **************************************************************************
685 * epoll interface for Linux 2.6
686 *
687 * Written by Christian Heimes
688 * Inspired by Twisted's _epoll.pyx and select.poll()
689 */
690
691#ifdef HAVE_SYS_EPOLL_H
692#include <sys/epoll.h>
693#endif
694
695typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000696 PyObject_HEAD
697 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000698} pyEpoll_Object;
699
700static PyTypeObject pyEpoll_Type;
701#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
702
703static PyObject *
704pyepoll_err_closed(void)
705{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000706 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
707 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000708}
709
710static int
711pyepoll_internal_close(pyEpoll_Object *self)
712{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000713 int save_errno = 0;
714 if (self->epfd >= 0) {
715 int epfd = self->epfd;
716 self->epfd = -1;
717 Py_BEGIN_ALLOW_THREADS
718 if (close(epfd) < 0)
719 save_errno = errno;
720 Py_END_ALLOW_THREADS
721 }
722 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000723}
724
725static PyObject *
726newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
727{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000728 pyEpoll_Object *self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000729
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000730 if (sizehint == -1) {
731 sizehint = FD_SETSIZE-1;
732 }
733 else if (sizehint < 1) {
734 PyErr_Format(PyExc_ValueError,
735 "sizehint must be greater zero, got %d",
736 sizehint);
737 return NULL;
738 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000739
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000740 assert(type != NULL && type->tp_alloc != NULL);
741 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
742 if (self == NULL)
743 return NULL;
744
745 if (fd == -1) {
746 Py_BEGIN_ALLOW_THREADS
747 self->epfd = epoll_create(sizehint);
748 Py_END_ALLOW_THREADS
749 }
750 else {
751 self->epfd = fd;
752 }
753 if (self->epfd < 0) {
754 Py_DECREF(self);
755 PyErr_SetFromErrno(PyExc_IOError);
756 return NULL;
757 }
758 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000759}
760
761
762static PyObject *
763pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
764{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000765 int sizehint = -1;
766 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000767
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000768 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
769 &sizehint))
770 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000771
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000772 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000773}
774
775
776static void
777pyepoll_dealloc(pyEpoll_Object *self)
778{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000779 (void)pyepoll_internal_close(self);
780 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000781}
782
783static PyObject*
784pyepoll_close(pyEpoll_Object *self)
785{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000786 errno = pyepoll_internal_close(self);
787 if (errno < 0) {
788 PyErr_SetFromErrno(PyExc_IOError);
789 return NULL;
790 }
791 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000792}
793
794PyDoc_STRVAR(pyepoll_close_doc,
795"close() -> None\n\
796\n\
797Close the epoll control file descriptor. Further operations on the epoll\n\
798object will raise an exception.");
799
800static PyObject*
801pyepoll_get_closed(pyEpoll_Object *self)
802{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000803 if (self->epfd < 0)
804 Py_RETURN_TRUE;
805 else
806 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000807}
808
809static PyObject*
810pyepoll_fileno(pyEpoll_Object *self)
811{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000812 if (self->epfd < 0)
813 return pyepoll_err_closed();
814 return PyInt_FromLong(self->epfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000815}
816
817PyDoc_STRVAR(pyepoll_fileno_doc,
818"fileno() -> int\n\
819\n\
820Return the epoll control file descriptor.");
821
822static PyObject*
823pyepoll_fromfd(PyObject *cls, PyObject *args)
824{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000825 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000826
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000827 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
828 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000829
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000830 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000831}
832
833PyDoc_STRVAR(pyepoll_fromfd_doc,
834"fromfd(fd) -> epoll\n\
835\n\
836Create an epoll object from a given control fd.");
837
838static PyObject *
839pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
840{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000841 struct epoll_event ev;
842 int result;
843 int fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000844
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000845 if (epfd < 0)
846 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000847
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 fd = PyObject_AsFileDescriptor(pfd);
849 if (fd == -1) {
850 return NULL;
851 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000852
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000853 switch(op) {
854 case EPOLL_CTL_ADD:
855 case EPOLL_CTL_MOD:
856 ev.events = events;
857 ev.data.fd = fd;
858 Py_BEGIN_ALLOW_THREADS
859 result = epoll_ctl(epfd, op, fd, &ev);
860 Py_END_ALLOW_THREADS
861 break;
862 case EPOLL_CTL_DEL:
863 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
864 * operation required a non-NULL pointer in event, even
865 * though this argument is ignored. */
866 Py_BEGIN_ALLOW_THREADS
867 result = epoll_ctl(epfd, op, fd, &ev);
868 if (errno == EBADF) {
869 /* fd already closed */
870 result = 0;
871 errno = 0;
872 }
873 Py_END_ALLOW_THREADS
874 break;
875 default:
876 result = -1;
877 errno = EINVAL;
878 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000879
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000880 if (result < 0) {
881 PyErr_SetFromErrno(PyExc_IOError);
882 return NULL;
883 }
884 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000885}
886
887static PyObject *
888pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
889{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000890 PyObject *pfd;
891 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
892 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000893
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000894 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
895 &pfd, &events)) {
896 return NULL;
897 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000898
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000899 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000900}
901
902PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl7d4bfb32010-08-02 21:44:25 +0000903"register(fd[, eventmask]) -> None\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000904\n\
Senthil Kumaran2bd91002011-06-26 23:50:35 -0700905Registers a new fd or raises an IOError if the fd is already registered.\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000906fd is the target file descriptor of the operation.\n\
907events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000908is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
909\n\
910The epoll interface supports all file descriptors that support poll.");
911
912static PyObject *
913pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
914{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000915 PyObject *pfd;
916 unsigned int events;
917 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000918
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000919 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
920 &pfd, &events)) {
921 return NULL;
922 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000923
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000924 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000925}
926
927PyDoc_STRVAR(pyepoll_modify_doc,
928"modify(fd, eventmask) -> None\n\
929\n\
930fd is the target file descriptor of the operation\n\
931events is a bit set composed of the various EPOLL constants");
932
933static PyObject *
934pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
935{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000936 PyObject *pfd;
937 static char *kwlist[] = {"fd", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000938
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000939 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
940 &pfd)) {
941 return NULL;
942 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000943
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000944 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000945}
946
947PyDoc_STRVAR(pyepoll_unregister_doc,
948"unregister(fd) -> None\n\
949\n\
950fd is the target file descriptor of the operation.");
951
952static PyObject *
953pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
954{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000955 double dtimeout = -1.;
956 int timeout;
957 int maxevents = -1;
958 int nfds, i;
959 PyObject *elist = NULL, *etuple = NULL;
960 struct epoll_event *evs = NULL;
961 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000962
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000963 if (self->epfd < 0)
964 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000965
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000966 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
967 &dtimeout, &maxevents)) {
968 return NULL;
969 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000970
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000971 if (dtimeout < 0) {
972 timeout = -1;
973 }
974 else if (dtimeout * 1000.0 > INT_MAX) {
975 PyErr_SetString(PyExc_OverflowError,
976 "timeout is too large");
977 return NULL;
978 }
979 else {
980 timeout = (int)(dtimeout * 1000.0);
981 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000982
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000983 if (maxevents == -1) {
984 maxevents = FD_SETSIZE-1;
985 }
986 else if (maxevents < 1) {
987 PyErr_Format(PyExc_ValueError,
988 "maxevents must be greater than 0, got %d",
989 maxevents);
990 return NULL;
991 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000992
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 evs = PyMem_New(struct epoll_event, maxevents);
994 if (evs == NULL) {
995 Py_DECREF(self);
996 PyErr_NoMemory();
997 return NULL;
998 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000999
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001000 Py_BEGIN_ALLOW_THREADS
1001 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1002 Py_END_ALLOW_THREADS
1003 if (nfds < 0) {
1004 PyErr_SetFromErrno(PyExc_IOError);
1005 goto error;
1006 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001007
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001008 elist = PyList_New(nfds);
1009 if (elist == NULL) {
1010 goto error;
1011 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001012
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001013 for (i = 0; i < nfds; i++) {
1014 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1015 if (etuple == NULL) {
1016 Py_CLEAR(elist);
1017 goto error;
1018 }
1019 PyList_SET_ITEM(elist, i, etuple);
1020 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001021
Georg Brandl018a3622008-03-26 12:57:47 +00001022 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001023 PyMem_Free(evs);
1024 return elist;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001025}
1026
1027PyDoc_STRVAR(pyepoll_poll_doc,
1028"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1029\n\
1030Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1031in seconds (as float). -1 makes poll wait indefinitely.\n\
1032Up to maxevents are returned to the caller.");
1033
1034static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001035 {"fromfd", (PyCFunction)pyepoll_fromfd,
1036 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1037 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1038 pyepoll_close_doc},
1039 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1040 pyepoll_fileno_doc},
1041 {"modify", (PyCFunction)pyepoll_modify,
1042 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1043 {"register", (PyCFunction)pyepoll_register,
1044 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1045 {"unregister", (PyCFunction)pyepoll_unregister,
1046 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1047 {"poll", (PyCFunction)pyepoll_poll,
1048 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1049 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001050};
1051
1052static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001053 {"closed", (getter)pyepoll_get_closed, NULL,
1054 "True if the epoll handler is closed"},
1055 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001056};
1057
1058PyDoc_STRVAR(pyepoll_doc,
1059"select.epoll([sizehint=-1])\n\
1060\n\
1061Returns an epolling object\n\
1062\n\
1063sizehint must be a positive integer or -1 for the default size. The\n\
1064sizehint is used to optimize internal data structures. It doesn't limit\n\
1065the maximum number of monitored events.");
1066
1067static PyTypeObject pyEpoll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001068 PyVarObject_HEAD_INIT(NULL, 0)
1069 "select.epoll", /* tp_name */
1070 sizeof(pyEpoll_Object), /* tp_basicsize */
1071 0, /* tp_itemsize */
1072 (destructor)pyepoll_dealloc, /* tp_dealloc */
1073 0, /* tp_print */
1074 0, /* tp_getattr */
1075 0, /* tp_setattr */
1076 0, /* tp_compare */
1077 0, /* tp_repr */
1078 0, /* tp_as_number */
1079 0, /* tp_as_sequence */
1080 0, /* tp_as_mapping */
1081 0, /* tp_hash */
1082 0, /* tp_call */
1083 0, /* tp_str */
1084 PyObject_GenericGetAttr, /* tp_getattro */
1085 0, /* tp_setattro */
1086 0, /* tp_as_buffer */
1087 Py_TPFLAGS_DEFAULT, /* tp_flags */
1088 pyepoll_doc, /* tp_doc */
1089 0, /* tp_traverse */
1090 0, /* tp_clear */
1091 0, /* tp_richcompare */
1092 0, /* tp_weaklistoffset */
1093 0, /* tp_iter */
1094 0, /* tp_iternext */
1095 pyepoll_methods, /* tp_methods */
1096 0, /* tp_members */
1097 pyepoll_getsetlist, /* tp_getset */
1098 0, /* tp_base */
1099 0, /* tp_dict */
1100 0, /* tp_descr_get */
1101 0, /* tp_descr_set */
1102 0, /* tp_dictoffset */
1103 0, /* tp_init */
1104 0, /* tp_alloc */
1105 pyepoll_new, /* tp_new */
1106 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001107};
1108
1109#endif /* HAVE_EPOLL */
1110
1111#ifdef HAVE_KQUEUE
1112/* **************************************************************************
1113 * kqueue interface for BSD
1114 *
1115 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1116 * All rights reserved.
1117 *
1118 * Redistribution and use in source and binary forms, with or without
1119 * modification, are permitted provided that the following conditions
1120 * are met:
1121 * 1. Redistributions of source code must retain the above copyright
1122 * notice, this list of conditions and the following disclaimer.
1123 * 2. Redistributions in binary form must reproduce the above copyright
1124 * notice, this list of conditions and the following disclaimer in the
1125 * documentation and/or other materials provided with the distribution.
1126 *
1127 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1128 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1129 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1130 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1131 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1132 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1133 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1134 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1135 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1136 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1137 * SUCH DAMAGE.
1138 */
1139
1140#ifdef HAVE_SYS_EVENT_H
1141#include <sys/event.h>
1142#endif
1143
1144PyDoc_STRVAR(kqueue_event_doc,
Georg Brandlfa1ffb62009-12-29 21:09:17 +00001145"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001146\n\
1147This object is the equivalent of the struct kevent for the C API.\n\
1148\n\
1149See the kqueue manpage for more detailed information about the meaning\n\
1150of the arguments.\n\
1151\n\
1152One minor note: while you might hope that udata could store a\n\
1153reference to a python object, it cannot, because it is impossible to\n\
1154keep a proper reference count of the object once it's passed into the\n\
1155kernel. Therefore, I have restricted it to only storing an integer. I\n\
1156recommend ignoring it and simply using the 'ident' field to key off\n\
1157of. You could also set up a dictionary on the python side to store a\n\
1158udata->object mapping.");
1159
1160typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001161 PyObject_HEAD
1162 struct kevent e;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001163} kqueue_event_Object;
1164
1165static PyTypeObject kqueue_event_Type;
1166
1167#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1168
1169typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001170 PyObject_HEAD
1171 SOCKET kqfd; /* kqueue control fd */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001172} kqueue_queue_Object;
1173
1174static PyTypeObject kqueue_queue_Type;
1175
1176#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1177
Antoine Pitrou323b9da2009-11-04 19:25:14 +00001178#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1179# error uintptr_t does not match void *!
1180#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1181# define T_UINTPTRT T_ULONGLONG
1182# define T_INTPTRT T_LONGLONG
1183# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1184# define UINTPTRT_FMT_UNIT "K"
1185# define INTPTRT_FMT_UNIT "L"
1186#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1187# define T_UINTPTRT T_ULONG
1188# define T_INTPTRT T_LONG
1189# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1190# define UINTPTRT_FMT_UNIT "k"
1191# define INTPTRT_FMT_UNIT "l"
1192#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1193# define T_UINTPTRT T_UINT
1194# define T_INTPTRT T_INT
1195# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1196# define UINTPTRT_FMT_UNIT "I"
1197# define INTPTRT_FMT_UNIT "i"
1198#else
1199# error uintptr_t does not match int, long, or long long!
1200#endif
1201
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001202/* Unfortunately, we can't store python objects in udata, because
1203 * kevents in the kernel can be removed without warning, which would
1204 * forever lose the refcount on the object stored with it.
1205 */
1206
1207#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1208static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001209 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1210 {"filter", T_SHORT, KQ_OFF(e.filter)},
1211 {"flags", T_USHORT, KQ_OFF(e.flags)},
1212 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1213 {"data", T_INTPTRT, KQ_OFF(e.data)},
1214 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1215 {NULL} /* Sentinel */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001216};
1217#undef KQ_OFF
1218
1219static PyObject *
Georg Brandlea370a92010-02-23 21:48:57 +00001220
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001221kqueue_event_repr(kqueue_event_Object *s)
1222{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001223 char buf[1024];
1224 PyOS_snprintf(
1225 buf, sizeof(buf),
1226 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1227 "data=0x%zd udata=%p>",
1228 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1229 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1230 return PyString_FromString(buf);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001231}
1232
1233static int
1234kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1235{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001236 PyObject *pfd;
1237 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1238 "data", "udata", NULL};
1239 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001240
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001241 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001242
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001243 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1244 &pfd, &(self->e.filter), &(self->e.flags),
1245 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1246 return -1;
1247 }
1248
1249 if (PyLong_Check(pfd)) {
1250 self->e.ident = PyLong_AsUintptr_t(pfd);
1251 }
1252 else {
1253 self->e.ident = PyObject_AsFileDescriptor(pfd);
1254 }
1255 if (PyErr_Occurred()) {
1256 return -1;
1257 }
1258 return 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001259}
1260
1261static PyObject *
1262kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001263 int op)
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001264{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001265 Py_intptr_t result = 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001266
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001267 if (!kqueue_event_Check(o)) {
1268 if (op == Py_EQ || op == Py_NE) {
1269 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1270 Py_INCREF(res);
1271 return res;
1272 }
1273 PyErr_Format(PyExc_TypeError,
1274 "can't compare %.200s to %.200s",
1275 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1276 return NULL;
1277 }
1278 if (((result = s->e.ident - o->e.ident) == 0) &&
1279 ((result = s->e.filter - o->e.filter) == 0) &&
1280 ((result = s->e.flags - o->e.flags) == 0) &&
1281 ((result = s->e.fflags - o->e.fflags) == 0) &&
1282 ((result = s->e.data - o->e.data) == 0) &&
1283 ((result = s->e.udata - o->e.udata) == 0)
1284 ) {
1285 result = 0;
1286 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001287
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001288 switch (op) {
1289 case Py_EQ:
1290 result = (result == 0);
1291 break;
1292 case Py_NE:
1293 result = (result != 0);
1294 break;
1295 case Py_LE:
1296 result = (result <= 0);
1297 break;
1298 case Py_GE:
1299 result = (result >= 0);
1300 break;
1301 case Py_LT:
1302 result = (result < 0);
1303 break;
1304 case Py_GT:
1305 result = (result > 0);
1306 break;
1307 }
1308 return PyBool_FromLong((long)result);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001309}
1310
1311static PyTypeObject kqueue_event_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001312 PyVarObject_HEAD_INIT(NULL, 0)
1313 "select.kevent", /* tp_name */
1314 sizeof(kqueue_event_Object), /* tp_basicsize */
1315 0, /* tp_itemsize */
1316 0, /* tp_dealloc */
1317 0, /* tp_print */
1318 0, /* tp_getattr */
1319 0, /* tp_setattr */
1320 0, /* tp_compare */
1321 (reprfunc)kqueue_event_repr, /* tp_repr */
1322 0, /* tp_as_number */
1323 0, /* tp_as_sequence */
1324 0, /* tp_as_mapping */
1325 0, /* tp_hash */
1326 0, /* tp_call */
1327 0, /* tp_str */
1328 0, /* tp_getattro */
1329 0, /* tp_setattro */
1330 0, /* tp_as_buffer */
1331 Py_TPFLAGS_DEFAULT, /* tp_flags */
1332 kqueue_event_doc, /* tp_doc */
1333 0, /* tp_traverse */
1334 0, /* tp_clear */
1335 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1336 0, /* tp_weaklistoffset */
1337 0, /* tp_iter */
1338 0, /* tp_iternext */
1339 0, /* tp_methods */
1340 kqueue_event_members, /* tp_members */
1341 0, /* tp_getset */
1342 0, /* tp_base */
1343 0, /* tp_dict */
1344 0, /* tp_descr_get */
1345 0, /* tp_descr_set */
1346 0, /* tp_dictoffset */
1347 (initproc)kqueue_event_init, /* tp_init */
1348 0, /* tp_alloc */
1349 0, /* tp_new */
1350 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001351};
1352
1353static PyObject *
1354kqueue_queue_err_closed(void)
1355{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001356 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1357 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001358}
1359
1360static int
1361kqueue_queue_internal_close(kqueue_queue_Object *self)
1362{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 int save_errno = 0;
1364 if (self->kqfd >= 0) {
1365 int kqfd = self->kqfd;
1366 self->kqfd = -1;
1367 Py_BEGIN_ALLOW_THREADS
1368 if (close(kqfd) < 0)
1369 save_errno = errno;
1370 Py_END_ALLOW_THREADS
1371 }
1372 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001373}
1374
1375static PyObject *
1376newKqueue_Object(PyTypeObject *type, SOCKET fd)
1377{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001378 kqueue_queue_Object *self;
1379 assert(type != NULL && type->tp_alloc != NULL);
1380 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1381 if (self == NULL) {
1382 return NULL;
1383 }
1384
1385 if (fd == -1) {
1386 Py_BEGIN_ALLOW_THREADS
1387 self->kqfd = kqueue();
1388 Py_END_ALLOW_THREADS
1389 }
1390 else {
1391 self->kqfd = fd;
1392 }
1393 if (self->kqfd < 0) {
1394 Py_DECREF(self);
1395 PyErr_SetFromErrno(PyExc_IOError);
1396 return NULL;
1397 }
1398 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001399}
1400
1401static PyObject *
1402kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1403{
1404
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001405 if ((args != NULL && PyObject_Size(args)) ||
1406 (kwds != NULL && PyObject_Size(kwds))) {
1407 PyErr_SetString(PyExc_ValueError,
1408 "select.kqueue doesn't accept arguments");
1409 return NULL;
1410 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001411
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001412 return newKqueue_Object(type, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001413}
1414
1415static void
1416kqueue_queue_dealloc(kqueue_queue_Object *self)
1417{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001418 kqueue_queue_internal_close(self);
1419 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001420}
1421
1422static PyObject*
1423kqueue_queue_close(kqueue_queue_Object *self)
1424{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001425 errno = kqueue_queue_internal_close(self);
1426 if (errno < 0) {
1427 PyErr_SetFromErrno(PyExc_IOError);
1428 return NULL;
1429 }
1430 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001431}
1432
1433PyDoc_STRVAR(kqueue_queue_close_doc,
1434"close() -> None\n\
1435\n\
1436Close the kqueue control file descriptor. Further operations on the kqueue\n\
1437object will raise an exception.");
1438
1439static PyObject*
1440kqueue_queue_get_closed(kqueue_queue_Object *self)
1441{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001442 if (self->kqfd < 0)
1443 Py_RETURN_TRUE;
1444 else
1445 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001446}
1447
1448static PyObject*
1449kqueue_queue_fileno(kqueue_queue_Object *self)
1450{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001451 if (self->kqfd < 0)
1452 return kqueue_queue_err_closed();
1453 return PyInt_FromLong(self->kqfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001454}
1455
1456PyDoc_STRVAR(kqueue_queue_fileno_doc,
1457"fileno() -> int\n\
1458\n\
1459Return the kqueue control file descriptor.");
1460
1461static PyObject*
1462kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1463{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001464 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001465
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001466 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1467 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001468
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001469 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001470}
1471
1472PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1473"fromfd(fd) -> kqueue\n\
1474\n\
1475Create a kqueue object from a given control fd.");
1476
1477static PyObject *
1478kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1479{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001480 int nevents = 0;
1481 int gotevents = 0;
1482 int nchanges = 0;
1483 int i = 0;
1484 PyObject *otimeout = NULL;
1485 PyObject *ch = NULL;
1486 PyObject *it = NULL, *ei = NULL;
1487 PyObject *result = NULL;
1488 struct kevent *evl = NULL;
1489 struct kevent *chl = NULL;
1490 struct timespec timeoutspec;
1491 struct timespec *ptimeoutspec;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001492
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001493 if (self->kqfd < 0)
1494 return kqueue_queue_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001495
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001496 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1497 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001498
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001499 if (nevents < 0) {
1500 PyErr_Format(PyExc_ValueError,
1501 "Length of eventlist must be 0 or positive, got %d",
1502 nevents);
1503 return NULL;
1504 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001505
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001506 if (otimeout == Py_None || otimeout == NULL) {
1507 ptimeoutspec = NULL;
1508 }
1509 else if (PyNumber_Check(otimeout)) {
1510 double timeout;
1511 long seconds;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001512
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001513 timeout = PyFloat_AsDouble(otimeout);
1514 if (timeout == -1 && PyErr_Occurred())
1515 return NULL;
1516 if (timeout > (double)LONG_MAX) {
1517 PyErr_SetString(PyExc_OverflowError,
1518 "timeout period too long");
1519 return NULL;
1520 }
1521 if (timeout < 0) {
1522 PyErr_SetString(PyExc_ValueError,
1523 "timeout must be positive or None");
1524 return NULL;
1525 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001526
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001527 seconds = (long)timeout;
1528 timeout = timeout - (double)seconds;
1529 timeoutspec.tv_sec = seconds;
1530 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1531 ptimeoutspec = &timeoutspec;
1532 }
1533 else {
1534 PyErr_Format(PyExc_TypeError,
1535 "timeout argument must be an number "
1536 "or None, got %.200s",
1537 Py_TYPE(otimeout)->tp_name);
1538 return NULL;
1539 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001540
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001541 if (ch != NULL && ch != Py_None) {
1542 it = PyObject_GetIter(ch);
1543 if (it == NULL) {
1544 PyErr_SetString(PyExc_TypeError,
1545 "changelist is not iterable");
1546 return NULL;
1547 }
1548 nchanges = PyObject_Size(ch);
1549 if (nchanges < 0) {
1550 goto error;
1551 }
Georg Brandlea370a92010-02-23 21:48:57 +00001552
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001553 chl = PyMem_New(struct kevent, nchanges);
1554 if (chl == NULL) {
1555 PyErr_NoMemory();
1556 goto error;
1557 }
1558 i = 0;
1559 while ((ei = PyIter_Next(it)) != NULL) {
1560 if (!kqueue_event_Check(ei)) {
1561 Py_DECREF(ei);
1562 PyErr_SetString(PyExc_TypeError,
1563 "changelist must be an iterable of "
1564 "select.kevent objects");
1565 goto error;
1566 } else {
1567 chl[i++] = ((kqueue_event_Object *)ei)->e;
1568 }
1569 Py_DECREF(ei);
1570 }
1571 }
1572 Py_CLEAR(it);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001573
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001574 /* event list */
1575 if (nevents) {
1576 evl = PyMem_New(struct kevent, nevents);
1577 if (evl == NULL) {
1578 PyErr_NoMemory();
1579 goto error;
1580 }
1581 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001582
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001583 Py_BEGIN_ALLOW_THREADS
1584 gotevents = kevent(self->kqfd, chl, nchanges,
1585 evl, nevents, ptimeoutspec);
1586 Py_END_ALLOW_THREADS
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001587
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001588 if (gotevents == -1) {
1589 PyErr_SetFromErrno(PyExc_OSError);
1590 goto error;
1591 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001592
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001593 result = PyList_New(gotevents);
1594 if (result == NULL) {
1595 goto error;
1596 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001597
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001598 for (i = 0; i < gotevents; i++) {
1599 kqueue_event_Object *ch;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001600
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001601 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1602 if (ch == NULL) {
1603 goto error;
1604 }
1605 ch->e = evl[i];
1606 PyList_SET_ITEM(result, i, (PyObject *)ch);
1607 }
1608 PyMem_Free(chl);
1609 PyMem_Free(evl);
1610 return result;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001611
1612 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001613 PyMem_Free(chl);
1614 PyMem_Free(evl);
1615 Py_XDECREF(result);
1616 Py_XDECREF(it);
1617 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001618}
1619
1620PyDoc_STRVAR(kqueue_queue_control_doc,
Georg Brandl2f3bd832008-09-21 07:14:44 +00001621"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001622\n\
1623Calls the kernel kevent function.\n\
1624- changelist must be a list of kevent objects describing the changes\n\
1625 to be made to the kernel's watch list or None.\n\
1626- max_events lets you specify the maximum number of events that the\n\
1627 kernel will return.\n\
1628- timeout is the maximum time to wait in seconds, or else None,\n\
1629 to wait forever. timeout accepts floats for smaller timeouts, too.");
1630
1631
1632static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001633 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1634 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1635 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1636 kqueue_queue_close_doc},
1637 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1638 kqueue_queue_fileno_doc},
1639 {"control", (PyCFunction)kqueue_queue_control,
1640 METH_VARARGS , kqueue_queue_control_doc},
1641 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001642};
1643
1644static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001645 {"closed", (getter)kqueue_queue_get_closed, NULL,
1646 "True if the kqueue handler is closed"},
1647 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001648};
1649
1650PyDoc_STRVAR(kqueue_queue_doc,
1651"Kqueue syscall wrapper.\n\
1652\n\
1653For example, to start watching a socket for input:\n\
1654>>> kq = kqueue()\n\
1655>>> sock = socket()\n\
1656>>> sock.connect((host, port))\n\
1657>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1658\n\
1659To wait one second for it to become writeable:\n\
1660>>> kq.control(None, 1, 1000)\n\
1661\n\
1662To stop listening:\n\
1663>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1664
1665static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001666 PyVarObject_HEAD_INIT(NULL, 0)
1667 "select.kqueue", /* tp_name */
1668 sizeof(kqueue_queue_Object), /* tp_basicsize */
1669 0, /* tp_itemsize */
1670 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1671 0, /* tp_print */
1672 0, /* tp_getattr */
1673 0, /* tp_setattr */
1674 0, /* tp_compare */
1675 0, /* tp_repr */
1676 0, /* tp_as_number */
1677 0, /* tp_as_sequence */
1678 0, /* tp_as_mapping */
1679 0, /* tp_hash */
1680 0, /* tp_call */
1681 0, /* tp_str */
1682 0, /* tp_getattro */
1683 0, /* tp_setattro */
1684 0, /* tp_as_buffer */
1685 Py_TPFLAGS_DEFAULT, /* tp_flags */
1686 kqueue_queue_doc, /* tp_doc */
1687 0, /* tp_traverse */
1688 0, /* tp_clear */
1689 0, /* tp_richcompare */
1690 0, /* tp_weaklistoffset */
1691 0, /* tp_iter */
1692 0, /* tp_iternext */
1693 kqueue_queue_methods, /* tp_methods */
1694 0, /* tp_members */
1695 kqueue_queue_getsetlist, /* tp_getset */
1696 0, /* tp_base */
1697 0, /* tp_dict */
1698 0, /* tp_descr_get */
1699 0, /* tp_descr_set */
1700 0, /* tp_dictoffset */
1701 0, /* tp_init */
1702 0, /* tp_alloc */
1703 kqueue_queue_new, /* tp_new */
1704 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001705};
1706
1707#endif /* HAVE_KQUEUE */
1708/* ************************************************************************ */
1709
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001710PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001711"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1712\n\
1713Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001714The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001715rlist -- wait until ready for reading\n\
1716wlist -- wait until ready for writing\n\
1717xlist -- wait for an ``exceptional condition''\n\
1718If only one kind of condition is required, pass [] for the other lists.\n\
1719A file descriptor is either a socket or file object, or a small integer\n\
1720gotten from a fileno() method call on one of those.\n\
1721\n\
1722The optional 4th argument specifies a timeout in seconds; it may be\n\
1723a floating point number to specify fractions of seconds. If it is absent\n\
1724or None, the call will never time out.\n\
1725\n\
1726The return value is a tuple of three lists corresponding to the first three\n\
1727arguments; each contains the subset of the corresponding file descriptors\n\
1728that are ready.\n\
1729\n\
1730*** IMPORTANT NOTICE ***\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001731On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +00001732descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001733
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001734static PyMethodDef select_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001735 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001736#ifdef HAVE_POLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001737 {"poll", select_poll, METH_NOARGS, poll_doc},
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001738#endif /* HAVE_POLL */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001739 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001740};
1741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001742PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001743"This module supports asynchronous I/O on multiple file descriptors.\n\
1744\n\
1745*** IMPORTANT NOTICE ***\n\
Neal Norwitz2a30cd02006-07-10 01:18:57 +00001746On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001747
Mark Hammond62b1ab12002-07-23 06:31:15 +00001748PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001749initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001750{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001751 PyObject *m;
1752 m = Py_InitModule3("select", select_methods, module_doc);
1753 if (m == NULL)
1754 return;
Fred Drake4baedc12002-04-01 14:53:37 +00001755
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001756 SelectError = PyErr_NewException("select.error", NULL, NULL);
1757 Py_INCREF(SelectError);
1758 PyModule_AddObject(m, "error", SelectError);
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001759
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001760#ifdef PIPE_BUF
R. David Murray1d9d16e2010-10-16 00:43:13 +00001761#ifdef HAVE_BROKEN_PIPE_BUF
1762#undef PIPE_BUF
1763#define PIPE_BUF 512
1764#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001765 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001766#endif
Gregory P. Smith9d36fd22009-07-03 20:48:31 +00001767
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001768#if defined(HAVE_POLL)
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001769#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001770 if (select_have_broken_poll()) {
1771 if (PyObject_DelAttrString(m, "poll") == -1) {
1772 PyErr_Clear();
1773 }
1774 } else {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001775#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001776 {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001777#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001778 Py_TYPE(&poll_Type) = &PyType_Type;
1779 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1780 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1781 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1782 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1783 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1784 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001785
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001786#ifdef POLLRDNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001787 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001788#endif
1789#ifdef POLLRDBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001790 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001791#endif
1792#ifdef POLLWRNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001793 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001794#endif
1795#ifdef POLLWRBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001796 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001797#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001798#ifdef POLLMSG
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001799 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001800#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001801 }
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001802#endif /* HAVE_POLL */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001803
1804#ifdef HAVE_EPOLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001805 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1806 if (PyType_Ready(&pyEpoll_Type) < 0)
1807 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001808
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001809 Py_INCREF(&pyEpoll_Type);
1810 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001811
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001812 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1813 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1814 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1815 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1816 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1817 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001818#ifdef EPOLLONESHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001819 /* Kernel 2.6.2+ */
1820 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001821#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001822 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1823 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1824 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1825 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1826 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1827 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001828#endif /* HAVE_EPOLL */
1829
1830#ifdef HAVE_KQUEUE
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001831 kqueue_event_Type.tp_new = PyType_GenericNew;
1832 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1833 if(PyType_Ready(&kqueue_event_Type) < 0)
1834 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001835
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001836 Py_INCREF(&kqueue_event_Type);
1837 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001838
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001839 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1840 if(PyType_Ready(&kqueue_queue_Type) < 0)
1841 return;
1842 Py_INCREF(&kqueue_queue_Type);
1843 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1844
1845 /* event filters */
1846 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1847 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1848 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1849 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1850 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001851#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001852 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001853#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001854 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1855 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001856
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001857 /* event flags */
1858 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1859 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1860 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1861 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1862 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1863 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001864
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001865 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1866 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001867
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001868 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1869 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001870
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001871 /* READ WRITE filter flag */
1872 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001873
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001874 /* VNODE filter flags */
1875 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1876 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1877 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1878 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1879 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1880 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1881 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001882
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001883 /* PROC filter flags */
1884 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1885 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1886 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1887 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1888 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001889
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001890 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1891 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1892 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1893
1894 /* NETDEV filter flags */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001895#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001896 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1897 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1898 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001899#endif
1900
1901#endif /* HAVE_KQUEUE */
Guido van Rossumed233a51992-06-23 09:07:03 +00001902}