blob: e594b51f23ea96598f1d8ca0dc11b1ef41c413af [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /* Perform runtime testing for a broken poll on OSX to make it easier
12 * to use the same binary on multiple releases of the OS.
13 */
14#undef HAVE_BROKEN_POLL
15#endif
16
Tim Petersd92dfe02000-12-12 01:18:41 +000017/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
18 64 is too small (too many people have bumped into that limit).
19 Here we boost it.
20 Users who want even more than the boosted limit should #define
21 FD_SETSIZE higher before this; e.g., via compiler /D switch.
22*/
23#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
24#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000026
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000027#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#elif defined(HAVE_SYS_POLL_H)
30#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000031#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000032
Guido van Rossum37273171996-12-09 18:47:43 +000033#ifdef __sgi
34/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000035extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000036#endif
37
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000040#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000041
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000042#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000043#include <sys/time.h>
44#include <utils.h>
45#endif
46
Guido van Rossum6f489d91996-06-28 20:15:15 +000047#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000048# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000050#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000052# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053# include <socket.h>
54# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000057static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000058
Barry Warsawc1cb3601996-12-12 22:16:21 +000059/* list of Python objects and their file descriptor */
60typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 PyObject *obj; /* owned reference */
62 SOCKET fd;
63 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000064} pylist;
65
Barry Warsawc1cb3601996-12-12 22:16:21 +000066static void
Tim Peters4b046c22001-08-16 21:59:46 +000067reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 int i;
70 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
71 Py_XDECREF(fd2obj[i].obj);
72 fd2obj[i].obj = NULL;
73 }
74 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000075}
76
77
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000078/* returns -1 and sets the Python exception if an error occurred, otherwise
79 returns a number >= 0
80*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000081static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000082seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 int max = -1;
85 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000086 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 PyObject* fast_seq = NULL;
88 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
91 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000092
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000093 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 if (!fast_seq)
95 return -1;
96
97 len = PySequence_Fast_GET_SIZE(fast_seq);
98
99 for (i = 0; i < len; i++) {
100 SOCKET v;
101
102 /* any intervening fileno() calls could decr this refcnt */
103 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104 return -1;
105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 Py_INCREF(o);
107 v = PyObject_AsFileDescriptor( o );
108 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000109
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000110#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200113 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 PyErr_SetString(PyExc_ValueError,
115 "filedescriptor out of range in select()");
116 goto finally;
117 }
118 if (v > max)
119 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000120#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 /* add object and its file descriptor to the list */
124 if (index >= FD_SETSIZE) {
125 PyErr_SetString(PyExc_ValueError,
126 "too many file descriptors in select()");
127 goto finally;
128 }
129 fd2obj[index].obj = o;
130 fd2obj[index].fd = v;
131 fd2obj[index].sentinel = 0;
132 fd2obj[++index].sentinel = -1;
133 }
134 Py_DECREF(fast_seq);
135 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000136
137 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 Py_XDECREF(o);
139 Py_DECREF(fast_seq);
140 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000141}
142
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143/* returns NULL and sets the Python exception if an error occurred */
144static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000145set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 int i, j, count=0;
148 PyObject *list, *o;
149 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
152 if (FD_ISSET(fd2obj[j].fd, set))
153 count++;
154 }
155 list = PyList_New(count);
156 if (!list)
157 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 i = 0;
160 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
161 fd = fd2obj[j].fd;
162 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 o = fd2obj[j].obj;
164 fd2obj[j].obj = NULL;
165 /* transfer ownership */
166 if (PyList_SetItem(list, i, o) < 0)
167 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 i++;
170 }
171 }
172 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000173 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 Py_DECREF(list);
175 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000176}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177
Barry Warsawb44740f2001-08-16 16:52:59 +0000178#undef SELECT_USES_HEAP
179#if FD_SETSIZE > 1024
180#define SELECT_USES_HEAP
181#endif /* FD_SETSIZE > 1024 */
182
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000183static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000184select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000185{
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000188#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 /* XXX: All this should probably be implemented as follows:
190 * - find the highest descriptor we're interested in
191 * - add one
192 * - that's the size
193 * See: Stevens, APitUE, $12.5.1
194 */
195 pylist rfd2obj[FD_SETSIZE + 1];
196 pylist wfd2obj[FD_SETSIZE + 1];
197 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000198#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 PyObject *ifdlist, *ofdlist, *efdlist;
200 PyObject *ret = NULL;
201 PyObject *tout = Py_None;
202 fd_set ifdset, ofdset, efdset;
203 double timeout;
204 struct timeval tv, *tvp;
205 long seconds;
206 int imax, omax, emax, max;
207 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 /* convert arguments */
210 if (!PyArg_UnpackTuple(args, "select", 3, 4,
211 &ifdlist, &ofdlist, &efdlist, &tout))
212 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 if (tout == Py_None)
215 tvp = (struct timeval *)0;
216 else if (!PyNumber_Check(tout)) {
217 PyErr_SetString(PyExc_TypeError,
218 "timeout must be a float or None");
219 return NULL;
220 }
221 else {
222 timeout = PyFloat_AsDouble(tout);
223 if (timeout == -1 && PyErr_Occurred())
224 return NULL;
225 if (timeout > (double)LONG_MAX) {
226 PyErr_SetString(PyExc_OverflowError,
227 "timeout period too long");
228 return NULL;
229 }
Antoine Pitrou131a6412011-04-09 23:49:58 +0200230 if (timeout < 0) {
231 PyErr_SetString(PyExc_ValueError,
232 "timeout must be non-negative");
233 return NULL;
234 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 seconds = (long)timeout;
236 timeout = timeout - (double)seconds;
237 tv.tv_sec = seconds;
238 tv.tv_usec = (long)(timeout * 1E6);
239 tvp = &tv;
240 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000241
Guido van Rossumed233a51992-06-23 09:07:03 +0000242
Barry Warsawb44740f2001-08-16 16:52:59 +0000243#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 /* Allocate memory for the lists */
245 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
246 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
247 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
248 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
249 if (rfd2obj) PyMem_DEL(rfd2obj);
250 if (wfd2obj) PyMem_DEL(wfd2obj);
251 if (efd2obj) PyMem_DEL(efd2obj);
252 return PyErr_NoMemory();
253 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000254#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 /* Convert sequences to fd_sets, and get maximum fd number
256 * propagates the Python exception set in seq2set()
257 */
258 rfd2obj[0].sentinel = -1;
259 wfd2obj[0].sentinel = -1;
260 efd2obj[0].sentinel = -1;
261 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
262 goto finally;
263 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
264 goto finally;
265 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
266 goto finally;
267 max = imax;
268 if (omax > max) max = omax;
269 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 Py_BEGIN_ALLOW_THREADS
272 n = select(max, &ifdset, &ofdset, &efdset, tvp);
273 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000274
Thomas Heller106f4c72002-09-24 16:51:00 +0000275#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 if (n == SOCKET_ERROR) {
277 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
278 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000279#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 if (n < 0) {
281 PyErr_SetFromErrno(SelectError);
282 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000283#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 else {
285 /* any of these three calls can raise an exception. it's more
286 convenient to test for this after all three calls... but
287 is that acceptable?
288 */
289 ifdlist = set2list(&ifdset, rfd2obj);
290 ofdlist = set2list(&ofdset, wfd2obj);
291 efdlist = set2list(&efdset, efd2obj);
292 if (PyErr_Occurred())
293 ret = NULL;
294 else
295 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 Py_DECREF(ifdlist);
298 Py_DECREF(ofdlist);
299 Py_DECREF(efdlist);
300 }
301
Barry Warsawc1cb3601996-12-12 22:16:21 +0000302 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 reap_obj(rfd2obj);
304 reap_obj(wfd2obj);
305 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000306#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 PyMem_DEL(rfd2obj);
308 PyMem_DEL(wfd2obj);
309 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000310#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000312}
313
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000314#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000316 * poll() support
317 */
318
319typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 PyObject_HEAD
321 PyObject *dict;
322 int ufd_uptodate;
323 int ufd_len;
324 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000325} pollObject;
326
Jeremy Hylton938ace62002-07-17 16:30:39 +0000327static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000330 contained within a pollObject. Return 1 on success, 0 on an error.
331*/
332
333static int
334update_ufd_array(pollObject *self)
335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 Py_ssize_t i, pos;
337 PyObject *key, *value;
338 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 self->ufd_len = PyDict_Size(self->dict);
341 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
342 if (self->ufds == NULL) {
343 self->ufds = old_ufds;
344 PyErr_NoMemory();
345 return 0;
346 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 i = pos = 0;
349 while (PyDict_Next(self->dict, &pos, &key, &value)) {
350 self->ufds[i].fd = PyLong_AsLong(key);
351 self->ufds[i].events = (short)PyLong_AsLong(value);
352 i++;
353 }
354 self->ufd_uptodate = 1;
355 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000356}
357
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000358PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359"register(fd [, eventmask] ) -> None\n\n\
360Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000361fd -- either an integer, or an object with a fileno() method returning an\n\
362 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000363events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000364
365static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 PyObject *o, *key, *value;
369 int fd, events = POLLIN | POLLPRI | POLLOUT;
370 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
373 return NULL;
374 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 fd = PyObject_AsFileDescriptor(o);
377 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 /* Add entry to the internal dictionary: the key is the
380 file descriptor, and the value is the event mask. */
381 key = PyLong_FromLong(fd);
382 if (key == NULL)
383 return NULL;
384 value = PyLong_FromLong(events);
385 if (value == NULL) {
386 Py_DECREF(key);
387 return NULL;
388 }
389 err = PyDict_SetItem(self->dict, key, value);
390 Py_DECREF(key);
391 Py_DECREF(value);
392 if (err < 0)
393 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 self->ufd_uptodate = 0;
396
397 Py_INCREF(Py_None);
398 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000399}
400
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000401PyDoc_STRVAR(poll_modify_doc,
402"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000403Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000404fd -- either an integer, or an object with a fileno() method returning an\n\
405 int.\n\
406events -- an optional bitmask describing the type of events to check for");
407
408static PyObject *
409poll_modify(pollObject *self, PyObject *args)
410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 PyObject *o, *key, *value;
412 int fd, events;
413 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
416 return NULL;
417 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 fd = PyObject_AsFileDescriptor(o);
420 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 /* Modify registered fd */
423 key = PyLong_FromLong(fd);
424 if (key == NULL)
425 return NULL;
426 if (PyDict_GetItem(self->dict, key) == NULL) {
427 errno = ENOENT;
428 PyErr_SetFromErrno(PyExc_IOError);
429 return NULL;
430 }
431 value = PyLong_FromLong(events);
432 if (value == NULL) {
433 Py_DECREF(key);
434 return NULL;
435 }
436 err = PyDict_SetItem(self->dict, key, value);
437 Py_DECREF(key);
438 Py_DECREF(value);
439 if (err < 0)
440 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 self->ufd_uptodate = 0;
443
444 Py_INCREF(Py_None);
445 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000446}
447
448
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000449PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000451Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452
453static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 PyObject *key;
457 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 fd = PyObject_AsFileDescriptor( o );
460 if (fd == -1)
461 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 /* Check whether the fd is already in the array */
464 key = PyLong_FromLong(fd);
465 if (key == NULL)
466 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 if (PyDict_DelItem(self->dict, key) == -1) {
469 Py_DECREF(key);
470 /* This will simply raise the KeyError set by PyDict_DelItem
471 if the file descriptor isn't registered. */
472 return NULL;
473 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 Py_DECREF(key);
476 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 Py_INCREF(Py_None);
479 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480}
481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000482PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
484Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486
487static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 PyObject *result_list = NULL, *tout = NULL;
491 int timeout = 0, poll_result, i, j;
492 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
495 return NULL;
496 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Check values for timeout */
499 if (tout == NULL || tout == Py_None)
500 timeout = -1;
501 else if (!PyNumber_Check(tout)) {
502 PyErr_SetString(PyExc_TypeError,
503 "timeout must be an integer or None");
504 return NULL;
505 }
506 else {
507 tout = PyNumber_Long(tout);
508 if (!tout)
509 return NULL;
510 timeout = PyLong_AsLong(tout);
511 Py_DECREF(tout);
512 if (timeout == -1 && PyErr_Occurred())
513 return NULL;
514 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 /* Ensure the ufd array is up to date */
517 if (!self->ufd_uptodate)
518 if (update_ufd_array(self) == 0)
519 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 /* call poll() */
522 Py_BEGIN_ALLOW_THREADS
523 poll_result = poll(self->ufds, self->ufd_len, timeout);
524 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 if (poll_result < 0) {
527 PyErr_SetFromErrno(SelectError);
528 return NULL;
529 }
530
531 /* build the result list */
532
533 result_list = PyList_New(poll_result);
534 if (!result_list)
535 return NULL;
536 else {
537 for (i = 0, j = 0; j < poll_result; j++) {
538 /* skip to the next fired descriptor */
539 while (!self->ufds[i].revents) {
540 i++;
541 }
542 /* if we hit a NULL return, set value to NULL
543 and break out of loop; code at end will
544 clean up result_list */
545 value = PyTuple_New(2);
546 if (value == NULL)
547 goto error;
548 num = PyLong_FromLong(self->ufds[i].fd);
549 if (num == NULL) {
550 Py_DECREF(value);
551 goto error;
552 }
553 PyTuple_SET_ITEM(value, 0, num);
554
555 /* The &0xffff is a workaround for AIX. 'revents'
556 is a 16-bit short, and IBM assigned POLLNVAL
557 to be 0x8000, so the conversion to int results
558 in a negative number. See SF bug #923315. */
559 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
560 if (num == NULL) {
561 Py_DECREF(value);
562 goto error;
563 }
564 PyTuple_SET_ITEM(value, 1, num);
565 if ((PyList_SetItem(result_list, j, value)) == -1) {
566 Py_DECREF(value);
567 goto error;
568 }
569 i++;
570 }
571 }
572 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000573
574 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 Py_DECREF(result_list);
576 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000577}
578
579static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 {"register", (PyCFunction)poll_register,
581 METH_VARARGS, poll_register_doc},
582 {"modify", (PyCFunction)poll_modify,
583 METH_VARARGS, poll_modify_doc},
584 {"unregister", (PyCFunction)poll_unregister,
585 METH_O, poll_unregister_doc},
586 {"poll", (PyCFunction)poll_poll,
587 METH_VARARGS, poll_poll_doc},
588 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589};
590
591static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000592newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 pollObject *self;
595 self = PyObject_New(pollObject, &poll_Type);
596 if (self == NULL)
597 return NULL;
598 /* ufd_uptodate is a Boolean, denoting whether the
599 array pointed to by ufds matches the contents of the dictionary. */
600 self->ufd_uptodate = 0;
601 self->ufds = NULL;
602 self->dict = PyDict_New();
603 if (self->dict == NULL) {
604 Py_DECREF(self);
605 return NULL;
606 }
607 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000608}
609
610static void
611poll_dealloc(pollObject *self)
612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 if (self->ufds != NULL)
614 PyMem_DEL(self->ufds);
615 Py_XDECREF(self->dict);
616 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000617}
618
Tim Peters0c322792002-07-17 16:49:03 +0000619static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 /* The ob_type field must be initialized in the module init function
621 * to be portable to Windows without using C++. */
622 PyVarObject_HEAD_INIT(NULL, 0)
623 "select.poll", /*tp_name*/
624 sizeof(pollObject), /*tp_basicsize*/
625 0, /*tp_itemsize*/
626 /* methods */
627 (destructor)poll_dealloc, /*tp_dealloc*/
628 0, /*tp_print*/
629 0, /*tp_getattr*/
630 0, /*tp_setattr*/
631 0, /*tp_reserved*/
632 0, /*tp_repr*/
633 0, /*tp_as_number*/
634 0, /*tp_as_sequence*/
635 0, /*tp_as_mapping*/
636 0, /*tp_hash*/
637 0, /*tp_call*/
638 0, /*tp_str*/
639 0, /*tp_getattro*/
640 0, /*tp_setattro*/
641 0, /*tp_as_buffer*/
642 Py_TPFLAGS_DEFAULT, /*tp_flags*/
643 0, /*tp_doc*/
644 0, /*tp_traverse*/
645 0, /*tp_clear*/
646 0, /*tp_richcompare*/
647 0, /*tp_weaklistoffset*/
648 0, /*tp_iter*/
649 0, /*tp_iternext*/
650 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000651};
652
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000653PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000655unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000656
657static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000658select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000661}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000662
663#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665 * On some systems poll() sets errno on invalid file descriptors. We test
666 * for this at runtime because this bug may be fixed or introduced between
667 * OS releases.
668 */
669static int select_have_broken_poll(void)
670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 int poll_test;
672 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 /* Create a file descriptor to make invalid */
677 if (pipe(filedes) < 0) {
678 return 1;
679 }
680 poll_struct.fd = filedes[0];
681 close(filedes[0]);
682 close(filedes[1]);
683 poll_test = poll(&poll_struct, 1, 0);
684 if (poll_test < 0) {
685 return 1;
686 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
687 return 1;
688 }
689 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000690}
691#endif /* __APPLE__ */
692
693#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000694
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000695#ifdef HAVE_EPOLL
696/* **************************************************************************
697 * epoll interface for Linux 2.6
698 *
699 * Written by Christian Heimes
700 * Inspired by Twisted's _epoll.pyx and select.poll()
701 */
702
703#ifdef HAVE_SYS_EPOLL_H
704#include <sys/epoll.h>
705#endif
706
707typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 PyObject_HEAD
709 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000710} pyEpoll_Object;
711
712static PyTypeObject pyEpoll_Type;
713#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
714
715static PyObject *
716pyepoll_err_closed(void)
717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
719 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000720}
721
722static int
723pyepoll_internal_close(pyEpoll_Object *self)
724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 int save_errno = 0;
726 if (self->epfd >= 0) {
727 int epfd = self->epfd;
728 self->epfd = -1;
729 Py_BEGIN_ALLOW_THREADS
730 if (close(epfd) < 0)
731 save_errno = errno;
732 Py_END_ALLOW_THREADS
733 }
734 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000735}
736
737static PyObject *
738newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 if (sizehint == -1) {
743 sizehint = FD_SETSIZE-1;
744 }
745 else if (sizehint < 1) {
746 PyErr_Format(PyExc_ValueError,
747 "sizehint must be greater zero, got %d",
748 sizehint);
749 return NULL;
750 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 assert(type != NULL && type->tp_alloc != NULL);
753 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
754 if (self == NULL)
755 return NULL;
756
757 if (fd == -1) {
758 Py_BEGIN_ALLOW_THREADS
759 self->epfd = epoll_create(sizehint);
760 Py_END_ALLOW_THREADS
761 }
762 else {
763 self->epfd = fd;
764 }
765 if (self->epfd < 0) {
766 Py_DECREF(self);
767 PyErr_SetFromErrno(PyExc_IOError);
768 return NULL;
769 }
770 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000771}
772
773
774static PyObject *
775pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 int sizehint = -1;
778 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
781 &sizehint))
782 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000785}
786
787
788static void
789pyepoll_dealloc(pyEpoll_Object *self)
790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 (void)pyepoll_internal_close(self);
792 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000793}
794
795static PyObject*
796pyepoll_close(pyEpoll_Object *self)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 errno = pyepoll_internal_close(self);
799 if (errno < 0) {
800 PyErr_SetFromErrno(PyExc_IOError);
801 return NULL;
802 }
803 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000804}
805
806PyDoc_STRVAR(pyepoll_close_doc,
807"close() -> None\n\
808\n\
809Close the epoll control file descriptor. Further operations on the epoll\n\
810object will raise an exception.");
811
812static PyObject*
813pyepoll_get_closed(pyEpoll_Object *self)
814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 if (self->epfd < 0)
816 Py_RETURN_TRUE;
817 else
818 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000819}
820
821static PyObject*
822pyepoll_fileno(pyEpoll_Object *self)
823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 if (self->epfd < 0)
825 return pyepoll_err_closed();
826 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000827}
828
829PyDoc_STRVAR(pyepoll_fileno_doc,
830"fileno() -> int\n\
831\n\
832Return the epoll control file descriptor.");
833
834static PyObject*
835pyepoll_fromfd(PyObject *cls, PyObject *args)
836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
840 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000843}
844
845PyDoc_STRVAR(pyepoll_fromfd_doc,
846"fromfd(fd) -> epoll\n\
847\n\
848Create an epoll object from a given control fd.");
849
850static PyObject *
851pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 struct epoll_event ev;
854 int result;
855 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 if (epfd < 0)
858 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 fd = PyObject_AsFileDescriptor(pfd);
861 if (fd == -1) {
862 return NULL;
863 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 switch(op) {
866 case EPOLL_CTL_ADD:
867 case EPOLL_CTL_MOD:
868 ev.events = events;
869 ev.data.fd = fd;
870 Py_BEGIN_ALLOW_THREADS
871 result = epoll_ctl(epfd, op, fd, &ev);
872 Py_END_ALLOW_THREADS
873 break;
874 case EPOLL_CTL_DEL:
875 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
876 * operation required a non-NULL pointer in event, even
877 * though this argument is ignored. */
878 Py_BEGIN_ALLOW_THREADS
879 result = epoll_ctl(epfd, op, fd, &ev);
880 if (errno == EBADF) {
881 /* fd already closed */
882 result = 0;
883 errno = 0;
884 }
885 Py_END_ALLOW_THREADS
886 break;
887 default:
888 result = -1;
889 errno = EINVAL;
890 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 if (result < 0) {
893 PyErr_SetFromErrno(PyExc_IOError);
894 return NULL;
895 }
896 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000897}
898
899static PyObject *
900pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 PyObject *pfd;
903 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
904 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
907 &pfd, &events)) {
908 return NULL;
909 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000912}
913
914PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000915"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000916\n\
Senthil Kumaran7d80bd12011-06-26 23:48:23 -0700917Registers a new fd or raises an IOError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000918fd is the target file descriptor of the operation.\n\
919events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000920is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
921\n\
922The epoll interface supports all file descriptors that support poll.");
923
924static PyObject *
925pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
926{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 PyObject *pfd;
928 unsigned int events;
929 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
932 &pfd, &events)) {
933 return NULL;
934 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000937}
938
939PyDoc_STRVAR(pyepoll_modify_doc,
940"modify(fd, eventmask) -> None\n\
941\n\
942fd is the target file descriptor of the operation\n\
943events is a bit set composed of the various EPOLL constants");
944
945static PyObject *
946pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 PyObject *pfd;
949 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
952 &pfd)) {
953 return NULL;
954 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000957}
958
959PyDoc_STRVAR(pyepoll_unregister_doc,
960"unregister(fd) -> None\n\
961\n\
962fd is the target file descriptor of the operation.");
963
964static PyObject *
965pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
966{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 double dtimeout = -1.;
968 int timeout;
969 int maxevents = -1;
970 int nfds, i;
971 PyObject *elist = NULL, *etuple = NULL;
972 struct epoll_event *evs = NULL;
973 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 if (self->epfd < 0)
976 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
979 &dtimeout, &maxevents)) {
980 return NULL;
981 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 if (dtimeout < 0) {
984 timeout = -1;
985 }
986 else if (dtimeout * 1000.0 > INT_MAX) {
987 PyErr_SetString(PyExc_OverflowError,
988 "timeout is too large");
989 return NULL;
990 }
991 else {
992 timeout = (int)(dtimeout * 1000.0);
993 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 if (maxevents == -1) {
996 maxevents = FD_SETSIZE-1;
997 }
998 else if (maxevents < 1) {
999 PyErr_Format(PyExc_ValueError,
1000 "maxevents must be greater than 0, got %d",
1001 maxevents);
1002 return NULL;
1003 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 evs = PyMem_New(struct epoll_event, maxevents);
1006 if (evs == NULL) {
1007 Py_DECREF(self);
1008 PyErr_NoMemory();
1009 return NULL;
1010 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 Py_BEGIN_ALLOW_THREADS
1013 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1014 Py_END_ALLOW_THREADS
1015 if (nfds < 0) {
1016 PyErr_SetFromErrno(PyExc_IOError);
1017 goto error;
1018 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 elist = PyList_New(nfds);
1021 if (elist == NULL) {
1022 goto error;
1023 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 for (i = 0; i < nfds; i++) {
1026 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1027 if (etuple == NULL) {
1028 Py_CLEAR(elist);
1029 goto error;
1030 }
1031 PyList_SET_ITEM(elist, i, etuple);
1032 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001033
Christian Heimesf6cd9672008-03-26 13:45:42 +00001034 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 PyMem_Free(evs);
1036 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001037}
1038
1039PyDoc_STRVAR(pyepoll_poll_doc,
1040"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1041\n\
1042Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1043in seconds (as float). -1 makes poll wait indefinitely.\n\
1044Up to maxevents are returned to the caller.");
1045
1046static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 {"fromfd", (PyCFunction)pyepoll_fromfd,
1048 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1049 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1050 pyepoll_close_doc},
1051 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1052 pyepoll_fileno_doc},
1053 {"modify", (PyCFunction)pyepoll_modify,
1054 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1055 {"register", (PyCFunction)pyepoll_register,
1056 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1057 {"unregister", (PyCFunction)pyepoll_unregister,
1058 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1059 {"poll", (PyCFunction)pyepoll_poll,
1060 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1061 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001062};
1063
1064static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 {"closed", (getter)pyepoll_get_closed, NULL,
1066 "True if the epoll handler is closed"},
1067 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001068};
1069
1070PyDoc_STRVAR(pyepoll_doc,
1071"select.epoll([sizehint=-1])\n\
1072\n\
1073Returns an epolling object\n\
1074\n\
1075sizehint must be a positive integer or -1 for the default size. The\n\
1076sizehint is used to optimize internal data structures. It doesn't limit\n\
1077the maximum number of monitored events.");
1078
1079static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 PyVarObject_HEAD_INIT(NULL, 0)
1081 "select.epoll", /* tp_name */
1082 sizeof(pyEpoll_Object), /* tp_basicsize */
1083 0, /* tp_itemsize */
1084 (destructor)pyepoll_dealloc, /* tp_dealloc */
1085 0, /* tp_print */
1086 0, /* tp_getattr */
1087 0, /* tp_setattr */
1088 0, /* tp_reserved */
1089 0, /* tp_repr */
1090 0, /* tp_as_number */
1091 0, /* tp_as_sequence */
1092 0, /* tp_as_mapping */
1093 0, /* tp_hash */
1094 0, /* tp_call */
1095 0, /* tp_str */
1096 PyObject_GenericGetAttr, /* tp_getattro */
1097 0, /* tp_setattro */
1098 0, /* tp_as_buffer */
1099 Py_TPFLAGS_DEFAULT, /* tp_flags */
1100 pyepoll_doc, /* tp_doc */
1101 0, /* tp_traverse */
1102 0, /* tp_clear */
1103 0, /* tp_richcompare */
1104 0, /* tp_weaklistoffset */
1105 0, /* tp_iter */
1106 0, /* tp_iternext */
1107 pyepoll_methods, /* tp_methods */
1108 0, /* tp_members */
1109 pyepoll_getsetlist, /* tp_getset */
1110 0, /* tp_base */
1111 0, /* tp_dict */
1112 0, /* tp_descr_get */
1113 0, /* tp_descr_set */
1114 0, /* tp_dictoffset */
1115 0, /* tp_init */
1116 0, /* tp_alloc */
1117 pyepoll_new, /* tp_new */
1118 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001119};
1120
1121#endif /* HAVE_EPOLL */
1122
1123#ifdef HAVE_KQUEUE
1124/* **************************************************************************
1125 * kqueue interface for BSD
1126 *
1127 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1128 * All rights reserved.
1129 *
1130 * Redistribution and use in source and binary forms, with or without
1131 * modification, are permitted provided that the following conditions
1132 * are met:
1133 * 1. Redistributions of source code must retain the above copyright
1134 * notice, this list of conditions and the following disclaimer.
1135 * 2. Redistributions in binary form must reproduce the above copyright
1136 * notice, this list of conditions and the following disclaimer in the
1137 * documentation and/or other materials provided with the distribution.
1138 *
1139 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1140 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1141 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1142 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1143 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1144 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1145 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1146 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1147 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1148 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1149 * SUCH DAMAGE.
1150 */
1151
1152#ifdef HAVE_SYS_EVENT_H
1153#include <sys/event.h>
1154#endif
1155
1156PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001157"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001158\n\
1159This object is the equivalent of the struct kevent for the C API.\n\
1160\n\
1161See the kqueue manpage for more detailed information about the meaning\n\
1162of the arguments.\n\
1163\n\
1164One minor note: while you might hope that udata could store a\n\
1165reference to a python object, it cannot, because it is impossible to\n\
1166keep a proper reference count of the object once it's passed into the\n\
1167kernel. Therefore, I have restricted it to only storing an integer. I\n\
1168recommend ignoring it and simply using the 'ident' field to key off\n\
1169of. You could also set up a dictionary on the python side to store a\n\
1170udata->object mapping.");
1171
1172typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 PyObject_HEAD
1174 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001175} kqueue_event_Object;
1176
1177static PyTypeObject kqueue_event_Type;
1178
1179#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1180
1181typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 PyObject_HEAD
1183 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001184} kqueue_queue_Object;
1185
1186static PyTypeObject kqueue_queue_Type;
1187
1188#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1189
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001190#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1191# error uintptr_t does not match void *!
1192#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1193# define T_UINTPTRT T_ULONGLONG
1194# define T_INTPTRT T_LONGLONG
1195# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1196# define UINTPTRT_FMT_UNIT "K"
1197# define INTPTRT_FMT_UNIT "L"
1198#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1199# define T_UINTPTRT T_ULONG
1200# define T_INTPTRT T_LONG
1201# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1202# define UINTPTRT_FMT_UNIT "k"
1203# define INTPTRT_FMT_UNIT "l"
1204#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1205# define T_UINTPTRT T_UINT
1206# define T_INTPTRT T_INT
1207# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1208# define UINTPTRT_FMT_UNIT "I"
1209# define INTPTRT_FMT_UNIT "i"
1210#else
1211# error uintptr_t does not match int, long, or long long!
1212#endif
1213
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001214/* Unfortunately, we can't store python objects in udata, because
1215 * kevents in the kernel can be removed without warning, which would
1216 * forever lose the refcount on the object stored with it.
1217 */
1218
1219#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1220static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1222 {"filter", T_SHORT, KQ_OFF(e.filter)},
1223 {"flags", T_USHORT, KQ_OFF(e.flags)},
1224 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1225 {"data", T_INTPTRT, KQ_OFF(e.data)},
1226 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1227 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001228};
1229#undef KQ_OFF
1230
1231static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001232
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001233kqueue_event_repr(kqueue_event_Object *s)
1234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 char buf[1024];
1236 PyOS_snprintf(
1237 buf, sizeof(buf),
1238 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1239 "data=0x%zd udata=%p>",
1240 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1241 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1242 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001243}
1244
1245static int
1246kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 PyObject *pfd;
1249 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1250 "data", "udata", NULL};
1251 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1256 &pfd, &(self->e.filter), &(self->e.flags),
1257 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1258 return -1;
1259 }
1260
1261 if (PyLong_Check(pfd)) {
1262 self->e.ident = PyLong_AsUintptr_t(pfd);
1263 }
1264 else {
1265 self->e.ident = PyObject_AsFileDescriptor(pfd);
1266 }
1267 if (PyErr_Occurred()) {
1268 return -1;
1269 }
1270 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001271}
1272
1273static PyObject *
1274kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if (!kqueue_event_Check(o)) {
1280 if (op == Py_EQ || op == Py_NE) {
1281 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1282 Py_INCREF(res);
1283 return res;
1284 }
1285 PyErr_Format(PyExc_TypeError,
1286 "can't compare %.200s to %.200s",
1287 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1288 return NULL;
1289 }
1290 if (((result = s->e.ident - o->e.ident) == 0) &&
1291 ((result = s->e.filter - o->e.filter) == 0) &&
1292 ((result = s->e.flags - o->e.flags) == 0) &&
1293 ((result = s->e.fflags - o->e.fflags) == 0) &&
1294 ((result = s->e.data - o->e.data) == 0) &&
1295 ((result = s->e.udata - o->e.udata) == 0)
1296 ) {
1297 result = 0;
1298 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 switch (op) {
1301 case Py_EQ:
1302 result = (result == 0);
1303 break;
1304 case Py_NE:
1305 result = (result != 0);
1306 break;
1307 case Py_LE:
1308 result = (result <= 0);
1309 break;
1310 case Py_GE:
1311 result = (result >= 0);
1312 break;
1313 case Py_LT:
1314 result = (result < 0);
1315 break;
1316 case Py_GT:
1317 result = (result > 0);
1318 break;
1319 }
1320 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001321}
1322
1323static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 PyVarObject_HEAD_INIT(NULL, 0)
1325 "select.kevent", /* tp_name */
1326 sizeof(kqueue_event_Object), /* tp_basicsize */
1327 0, /* tp_itemsize */
1328 0, /* tp_dealloc */
1329 0, /* tp_print */
1330 0, /* tp_getattr */
1331 0, /* tp_setattr */
1332 0, /* tp_reserved */
1333 (reprfunc)kqueue_event_repr, /* tp_repr */
1334 0, /* tp_as_number */
1335 0, /* tp_as_sequence */
1336 0, /* tp_as_mapping */
1337 0, /* tp_hash */
1338 0, /* tp_call */
1339 0, /* tp_str */
1340 0, /* tp_getattro */
1341 0, /* tp_setattro */
1342 0, /* tp_as_buffer */
1343 Py_TPFLAGS_DEFAULT, /* tp_flags */
1344 kqueue_event_doc, /* tp_doc */
1345 0, /* tp_traverse */
1346 0, /* tp_clear */
1347 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1348 0, /* tp_weaklistoffset */
1349 0, /* tp_iter */
1350 0, /* tp_iternext */
1351 0, /* tp_methods */
1352 kqueue_event_members, /* tp_members */
1353 0, /* tp_getset */
1354 0, /* tp_base */
1355 0, /* tp_dict */
1356 0, /* tp_descr_get */
1357 0, /* tp_descr_set */
1358 0, /* tp_dictoffset */
1359 (initproc)kqueue_event_init, /* tp_init */
1360 0, /* tp_alloc */
1361 0, /* tp_new */
1362 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363};
1364
1365static PyObject *
1366kqueue_queue_err_closed(void)
1367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1369 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370}
1371
1372static int
1373kqueue_queue_internal_close(kqueue_queue_Object *self)
1374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 int save_errno = 0;
1376 if (self->kqfd >= 0) {
1377 int kqfd = self->kqfd;
1378 self->kqfd = -1;
1379 Py_BEGIN_ALLOW_THREADS
1380 if (close(kqfd) < 0)
1381 save_errno = errno;
1382 Py_END_ALLOW_THREADS
1383 }
1384 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001385}
1386
1387static PyObject *
1388newKqueue_Object(PyTypeObject *type, SOCKET fd)
1389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 kqueue_queue_Object *self;
1391 assert(type != NULL && type->tp_alloc != NULL);
1392 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1393 if (self == NULL) {
1394 return NULL;
1395 }
1396
1397 if (fd == -1) {
1398 Py_BEGIN_ALLOW_THREADS
1399 self->kqfd = kqueue();
1400 Py_END_ALLOW_THREADS
1401 }
1402 else {
1403 self->kqfd = fd;
1404 }
1405 if (self->kqfd < 0) {
1406 Py_DECREF(self);
1407 PyErr_SetFromErrno(PyExc_IOError);
1408 return NULL;
1409 }
1410 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001411}
1412
1413static PyObject *
1414kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1415{
1416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if ((args != NULL && PyObject_Size(args)) ||
1418 (kwds != NULL && PyObject_Size(kwds))) {
1419 PyErr_SetString(PyExc_ValueError,
1420 "select.kqueue doesn't accept arguments");
1421 return NULL;
1422 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425}
1426
1427static void
1428kqueue_queue_dealloc(kqueue_queue_Object *self)
1429{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 kqueue_queue_internal_close(self);
1431 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001432}
1433
1434static PyObject*
1435kqueue_queue_close(kqueue_queue_Object *self)
1436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 errno = kqueue_queue_internal_close(self);
1438 if (errno < 0) {
1439 PyErr_SetFromErrno(PyExc_IOError);
1440 return NULL;
1441 }
1442 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001443}
1444
1445PyDoc_STRVAR(kqueue_queue_close_doc,
1446"close() -> None\n\
1447\n\
1448Close the kqueue control file descriptor. Further operations on the kqueue\n\
1449object will raise an exception.");
1450
1451static PyObject*
1452kqueue_queue_get_closed(kqueue_queue_Object *self)
1453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 if (self->kqfd < 0)
1455 Py_RETURN_TRUE;
1456 else
1457 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001458}
1459
1460static PyObject*
1461kqueue_queue_fileno(kqueue_queue_Object *self)
1462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 if (self->kqfd < 0)
1464 return kqueue_queue_err_closed();
1465 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001466}
1467
1468PyDoc_STRVAR(kqueue_queue_fileno_doc,
1469"fileno() -> int\n\
1470\n\
1471Return the kqueue control file descriptor.");
1472
1473static PyObject*
1474kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1479 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001482}
1483
1484PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1485"fromfd(fd) -> kqueue\n\
1486\n\
1487Create a kqueue object from a given control fd.");
1488
1489static PyObject *
1490kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 int nevents = 0;
1493 int gotevents = 0;
1494 int nchanges = 0;
1495 int i = 0;
1496 PyObject *otimeout = NULL;
1497 PyObject *ch = NULL;
1498 PyObject *it = NULL, *ei = NULL;
1499 PyObject *result = NULL;
1500 struct kevent *evl = NULL;
1501 struct kevent *chl = NULL;
1502 struct timespec timeoutspec;
1503 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 if (self->kqfd < 0)
1506 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1509 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 if (nevents < 0) {
1512 PyErr_Format(PyExc_ValueError,
1513 "Length of eventlist must be 0 or positive, got %d",
1514 nevents);
1515 return NULL;
1516 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 if (otimeout == Py_None || otimeout == NULL) {
1519 ptimeoutspec = NULL;
1520 }
1521 else if (PyNumber_Check(otimeout)) {
1522 double timeout;
1523 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 timeout = PyFloat_AsDouble(otimeout);
1526 if (timeout == -1 && PyErr_Occurred())
1527 return NULL;
1528 if (timeout > (double)LONG_MAX) {
1529 PyErr_SetString(PyExc_OverflowError,
1530 "timeout period too long");
1531 return NULL;
1532 }
1533 if (timeout < 0) {
1534 PyErr_SetString(PyExc_ValueError,
1535 "timeout must be positive or None");
1536 return NULL;
1537 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 seconds = (long)timeout;
1540 timeout = timeout - (double)seconds;
1541 timeoutspec.tv_sec = seconds;
1542 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1543 ptimeoutspec = &timeoutspec;
1544 }
1545 else {
1546 PyErr_Format(PyExc_TypeError,
1547 "timeout argument must be an number "
1548 "or None, got %.200s",
1549 Py_TYPE(otimeout)->tp_name);
1550 return NULL;
1551 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 if (ch != NULL && ch != Py_None) {
1554 it = PyObject_GetIter(ch);
1555 if (it == NULL) {
1556 PyErr_SetString(PyExc_TypeError,
1557 "changelist is not iterable");
1558 return NULL;
1559 }
1560 nchanges = PyObject_Size(ch);
1561 if (nchanges < 0) {
1562 goto error;
1563 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 chl = PyMem_New(struct kevent, nchanges);
1566 if (chl == NULL) {
1567 PyErr_NoMemory();
1568 goto error;
1569 }
1570 i = 0;
1571 while ((ei = PyIter_Next(it)) != NULL) {
1572 if (!kqueue_event_Check(ei)) {
1573 Py_DECREF(ei);
1574 PyErr_SetString(PyExc_TypeError,
1575 "changelist must be an iterable of "
1576 "select.kevent objects");
1577 goto error;
1578 } else {
1579 chl[i++] = ((kqueue_event_Object *)ei)->e;
1580 }
1581 Py_DECREF(ei);
1582 }
1583 }
1584 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 /* event list */
1587 if (nevents) {
1588 evl = PyMem_New(struct kevent, nevents);
1589 if (evl == NULL) {
1590 PyErr_NoMemory();
1591 goto error;
1592 }
1593 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 Py_BEGIN_ALLOW_THREADS
1596 gotevents = kevent(self->kqfd, chl, nchanges,
1597 evl, nevents, ptimeoutspec);
1598 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 if (gotevents == -1) {
1601 PyErr_SetFromErrno(PyExc_OSError);
1602 goto error;
1603 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 result = PyList_New(gotevents);
1606 if (result == NULL) {
1607 goto error;
1608 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 for (i = 0; i < gotevents; i++) {
1611 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1614 if (ch == NULL) {
1615 goto error;
1616 }
1617 ch->e = evl[i];
1618 PyList_SET_ITEM(result, i, (PyObject *)ch);
1619 }
1620 PyMem_Free(chl);
1621 PyMem_Free(evl);
1622 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001623
1624 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 PyMem_Free(chl);
1626 PyMem_Free(evl);
1627 Py_XDECREF(result);
1628 Py_XDECREF(it);
1629 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630}
1631
1632PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001633"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634\n\
1635Calls the kernel kevent function.\n\
1636- changelist must be a list of kevent objects describing the changes\n\
1637 to be made to the kernel's watch list or None.\n\
1638- max_events lets you specify the maximum number of events that the\n\
1639 kernel will return.\n\
1640- timeout is the maximum time to wait in seconds, or else None,\n\
1641 to wait forever. timeout accepts floats for smaller timeouts, too.");
1642
1643
1644static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1646 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1647 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1648 kqueue_queue_close_doc},
1649 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1650 kqueue_queue_fileno_doc},
1651 {"control", (PyCFunction)kqueue_queue_control,
1652 METH_VARARGS , kqueue_queue_control_doc},
1653 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001654};
1655
1656static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 {"closed", (getter)kqueue_queue_get_closed, NULL,
1658 "True if the kqueue handler is closed"},
1659 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001660};
1661
1662PyDoc_STRVAR(kqueue_queue_doc,
1663"Kqueue syscall wrapper.\n\
1664\n\
1665For example, to start watching a socket for input:\n\
1666>>> kq = kqueue()\n\
1667>>> sock = socket()\n\
1668>>> sock.connect((host, port))\n\
1669>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1670\n\
1671To wait one second for it to become writeable:\n\
1672>>> kq.control(None, 1, 1000)\n\
1673\n\
1674To stop listening:\n\
1675>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1676
1677static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 PyVarObject_HEAD_INIT(NULL, 0)
1679 "select.kqueue", /* tp_name */
1680 sizeof(kqueue_queue_Object), /* tp_basicsize */
1681 0, /* tp_itemsize */
1682 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1683 0, /* tp_print */
1684 0, /* tp_getattr */
1685 0, /* tp_setattr */
1686 0, /* tp_reserved */
1687 0, /* tp_repr */
1688 0, /* tp_as_number */
1689 0, /* tp_as_sequence */
1690 0, /* tp_as_mapping */
1691 0, /* tp_hash */
1692 0, /* tp_call */
1693 0, /* tp_str */
1694 0, /* tp_getattro */
1695 0, /* tp_setattro */
1696 0, /* tp_as_buffer */
1697 Py_TPFLAGS_DEFAULT, /* tp_flags */
1698 kqueue_queue_doc, /* tp_doc */
1699 0, /* tp_traverse */
1700 0, /* tp_clear */
1701 0, /* tp_richcompare */
1702 0, /* tp_weaklistoffset */
1703 0, /* tp_iter */
1704 0, /* tp_iternext */
1705 kqueue_queue_methods, /* tp_methods */
1706 0, /* tp_members */
1707 kqueue_queue_getsetlist, /* tp_getset */
1708 0, /* tp_base */
1709 0, /* tp_dict */
1710 0, /* tp_descr_get */
1711 0, /* tp_descr_set */
1712 0, /* tp_dictoffset */
1713 0, /* tp_init */
1714 0, /* tp_alloc */
1715 kqueue_queue_new, /* tp_new */
1716 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001717};
1718
1719#endif /* HAVE_KQUEUE */
1720/* ************************************************************************ */
1721
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001722PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001723"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1724\n\
1725Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001726The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001727rlist -- wait until ready for reading\n\
1728wlist -- wait until ready for writing\n\
1729xlist -- wait for an ``exceptional condition''\n\
1730If only one kind of condition is required, pass [] for the other lists.\n\
1731A file descriptor is either a socket or file object, or a small integer\n\
1732gotten from a fileno() method call on one of those.\n\
1733\n\
1734The optional 4th argument specifies a timeout in seconds; it may be\n\
1735a floating point number to specify fractions of seconds. If it is absent\n\
1736or None, the call will never time out.\n\
1737\n\
1738The return value is a tuple of three lists corresponding to the first three\n\
1739arguments; each contains the subset of the corresponding file descriptors\n\
1740that are ready.\n\
1741\n\
1742*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001743On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001744descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001745
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001746static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001748#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001752};
1753
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001754PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001755"This module supports asynchronous I/O on multiple file descriptors.\n\
1756\n\
1757*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001758On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001759
Martin v. Löwis1a214512008-06-11 05:26:20 +00001760
1761static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 PyModuleDef_HEAD_INIT,
1763 "select",
1764 module_doc,
1765 -1,
1766 select_methods,
1767 NULL,
1768 NULL,
1769 NULL,
1770 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001771};
1772
Mark Hammond62b1ab12002-07-23 06:31:15 +00001773PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001774PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 PyObject *m;
1777 m = PyModule_Create(&selectmodule);
1778 if (m == NULL)
1779 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 SelectError = PyErr_NewException("select.error", NULL, NULL);
1782 Py_INCREF(SelectError);
1783 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001784
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001785#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001786#ifdef HAVE_BROKEN_PIPE_BUF
1787#undef PIPE_BUF
1788#define PIPE_BUF 512
1789#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001791#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001792
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001793#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 if (select_have_broken_poll()) {
1796 if (PyObject_DelAttrString(m, "poll") == -1) {
1797 PyErr_Clear();
1798 }
1799 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001802#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 if (PyType_Ready(&poll_Type) < 0)
1804 return NULL;
1805 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1806 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1807 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1808 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1809 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1810 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001811
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001812#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001814#endif
1815#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001817#endif
1818#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001820#endif
1821#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001823#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001824#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001826#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001828#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001829
1830#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1832 if (PyType_Ready(&pyEpoll_Type) < 0)
1833 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 Py_INCREF(&pyEpoll_Type);
1836 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1839 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1840 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1841 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1842 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1843 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001844#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 /* Kernel 2.6.2+ */
1846 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001847#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1849 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1850 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1851 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1852 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1853 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001854#endif /* HAVE_EPOLL */
1855
1856#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 kqueue_event_Type.tp_new = PyType_GenericNew;
1858 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1859 if(PyType_Ready(&kqueue_event_Type) < 0)
1860 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 Py_INCREF(&kqueue_event_Type);
1863 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1866 if(PyType_Ready(&kqueue_queue_Type) < 0)
1867 return NULL;
1868 Py_INCREF(&kqueue_queue_Type);
1869 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1870
1871 /* event filters */
1872 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1873 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1874 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1875 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1876 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001879#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1881 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 /* event flags */
1884 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1885 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1886 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1887 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1888 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1889 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1892 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1895 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 /* READ WRITE filter flag */
1898 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 /* VNODE filter flags */
1901 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1903 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1907 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 /* PROC filter flags */
1910 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1917 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1918 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1919
1920 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1923 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1924 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001925#endif
1926
1927#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001929}