blob: 5c475f5785995ed014b93ece14ac37254a56f98c [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 i;
85 int max = -1;
86 int index = 0;
87 int len = -1;
88 PyObject* fast_seq = NULL;
89 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
92 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000094 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (!fast_seq)
96 return -1;
97
98 len = PySequence_Fast_GET_SIZE(fast_seq);
99
100 for (i = 0; i < len; i++) {
101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000105 return -1;
106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 Py_INCREF(o);
108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#else /* !_MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 if (v < 0 || v >= FD_SETSIZE) {
115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
134 }
135 Py_DECREF(fast_seq);
136 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137
138 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 Py_XDECREF(o);
140 Py_DECREF(fast_seq);
141 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000142}
143
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144/* returns NULL and sets the Python exception if an error occurred */
145static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000146set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 int i, j, count=0;
149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
153 if (FD_ISSET(fd2obj[j].fd, set))
154 count++;
155 }
156 list = PyList_New(count);
157 if (!list)
158 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000164#ifndef _MSC_VER
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 if (fd > FD_SETSIZE) {
166 PyErr_SetString(PyExc_SystemError,
167 "filedescriptor out of range returned in select()");
168 goto finally;
169 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000170#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 o = fd2obj[j].obj;
172 fd2obj[j].obj = NULL;
173 /* transfer ownership */
174 if (PyList_SetItem(list, i, o) < 0)
175 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 i++;
178 }
179 }
180 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000181 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 Py_DECREF(list);
183 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000184}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000185
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#undef SELECT_USES_HEAP
187#if FD_SETSIZE > 1024
188#define SELECT_USES_HEAP
189#endif /* FD_SETSIZE > 1024 */
190
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000191static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000192select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000193{
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000196#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 /* XXX: All this should probably be implemented as follows:
198 * - find the highest descriptor we're interested in
199 * - add one
200 * - that's the size
201 * See: Stevens, APitUE, $12.5.1
202 */
203 pylist rfd2obj[FD_SETSIZE + 1];
204 pylist wfd2obj[FD_SETSIZE + 1];
205 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000206#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 PyObject *ifdlist, *ofdlist, *efdlist;
208 PyObject *ret = NULL;
209 PyObject *tout = Py_None;
210 fd_set ifdset, ofdset, efdset;
211 double timeout;
212 struct timeval tv, *tvp;
213 long seconds;
214 int imax, omax, emax, max;
215 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 /* convert arguments */
218 if (!PyArg_UnpackTuple(args, "select", 3, 4,
219 &ifdlist, &ofdlist, &efdlist, &tout))
220 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 if (tout == Py_None)
223 tvp = (struct timeval *)0;
224 else if (!PyNumber_Check(tout)) {
225 PyErr_SetString(PyExc_TypeError,
226 "timeout must be a float or None");
227 return NULL;
228 }
229 else {
230 timeout = PyFloat_AsDouble(tout);
231 if (timeout == -1 && PyErr_Occurred())
232 return NULL;
233 if (timeout > (double)LONG_MAX) {
234 PyErr_SetString(PyExc_OverflowError,
235 "timeout period too long");
236 return NULL;
237 }
238 seconds = (long)timeout;
239 timeout = timeout - (double)seconds;
240 tv.tv_sec = seconds;
241 tv.tv_usec = (long)(timeout * 1E6);
242 tvp = &tv;
243 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000244
Guido van Rossumed233a51992-06-23 09:07:03 +0000245
Barry Warsawb44740f2001-08-16 16:52:59 +0000246#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 /* Allocate memory for the lists */
248 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
249 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
250 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
251 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
252 if (rfd2obj) PyMem_DEL(rfd2obj);
253 if (wfd2obj) PyMem_DEL(wfd2obj);
254 if (efd2obj) PyMem_DEL(efd2obj);
255 return PyErr_NoMemory();
256 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000257#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 /* Convert sequences to fd_sets, and get maximum fd number
259 * propagates the Python exception set in seq2set()
260 */
261 rfd2obj[0].sentinel = -1;
262 wfd2obj[0].sentinel = -1;
263 efd2obj[0].sentinel = -1;
264 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
265 goto finally;
266 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
267 goto finally;
268 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
269 goto finally;
270 max = imax;
271 if (omax > max) max = omax;
272 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 Py_BEGIN_ALLOW_THREADS
275 n = select(max, &ifdset, &ofdset, &efdset, tvp);
276 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000277
Thomas Heller106f4c72002-09-24 16:51:00 +0000278#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 if (n == SOCKET_ERROR) {
280 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
281 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000282#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (n < 0) {
284 PyErr_SetFromErrno(SelectError);
285 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000286#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 else {
288 /* any of these three calls can raise an exception. it's more
289 convenient to test for this after all three calls... but
290 is that acceptable?
291 */
292 ifdlist = set2list(&ifdset, rfd2obj);
293 ofdlist = set2list(&ofdset, wfd2obj);
294 efdlist = set2list(&efdset, efd2obj);
295 if (PyErr_Occurred())
296 ret = NULL;
297 else
298 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 Py_DECREF(ifdlist);
301 Py_DECREF(ofdlist);
302 Py_DECREF(efdlist);
303 }
304
Barry Warsawc1cb3601996-12-12 22:16:21 +0000305 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 reap_obj(rfd2obj);
307 reap_obj(wfd2obj);
308 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000309#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 PyMem_DEL(rfd2obj);
311 PyMem_DEL(wfd2obj);
312 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000313#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000315}
316
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000317#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000319 * poll() support
320 */
321
322typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 PyObject_HEAD
324 PyObject *dict;
325 int ufd_uptodate;
326 int ufd_len;
327 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000328} pollObject;
329
Jeremy Hylton938ace62002-07-17 16:30:39 +0000330static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000333 contained within a pollObject. Return 1 on success, 0 on an error.
334*/
335
336static int
337update_ufd_array(pollObject *self)
338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 Py_ssize_t i, pos;
340 PyObject *key, *value;
341 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 self->ufd_len = PyDict_Size(self->dict);
344 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
345 if (self->ufds == NULL) {
346 self->ufds = old_ufds;
347 PyErr_NoMemory();
348 return 0;
349 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 i = pos = 0;
352 while (PyDict_Next(self->dict, &pos, &key, &value)) {
353 self->ufds[i].fd = PyLong_AsLong(key);
354 self->ufds[i].events = (short)PyLong_AsLong(value);
355 i++;
356 }
357 self->ufd_uptodate = 1;
358 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359}
360
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000361PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362"register(fd [, eventmask] ) -> None\n\n\
363Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000364fd -- either an integer, or an object with a fileno() method returning an\n\
365 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000366events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367
368static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 PyObject *o, *key, *value;
372 int fd, events = POLLIN | POLLPRI | POLLOUT;
373 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
376 return NULL;
377 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 fd = PyObject_AsFileDescriptor(o);
380 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 /* Add entry to the internal dictionary: the key is the
383 file descriptor, and the value is the event mask. */
384 key = PyLong_FromLong(fd);
385 if (key == NULL)
386 return NULL;
387 value = PyLong_FromLong(events);
388 if (value == NULL) {
389 Py_DECREF(key);
390 return NULL;
391 }
392 err = PyDict_SetItem(self->dict, key, value);
393 Py_DECREF(key);
394 Py_DECREF(value);
395 if (err < 0)
396 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 self->ufd_uptodate = 0;
399
400 Py_INCREF(Py_None);
401 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000402}
403
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000404PyDoc_STRVAR(poll_modify_doc,
405"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000406Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000407fd -- either an integer, or an object with a fileno() method returning an\n\
408 int.\n\
409events -- an optional bitmask describing the type of events to check for");
410
411static PyObject *
412poll_modify(pollObject *self, PyObject *args)
413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 PyObject *o, *key, *value;
415 int fd, events;
416 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
419 return NULL;
420 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 fd = PyObject_AsFileDescriptor(o);
423 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 /* Modify registered fd */
426 key = PyLong_FromLong(fd);
427 if (key == NULL)
428 return NULL;
429 if (PyDict_GetItem(self->dict, key) == NULL) {
430 errno = ENOENT;
431 PyErr_SetFromErrno(PyExc_IOError);
432 return NULL;
433 }
434 value = PyLong_FromLong(events);
435 if (value == NULL) {
436 Py_DECREF(key);
437 return NULL;
438 }
439 err = PyDict_SetItem(self->dict, key, value);
440 Py_DECREF(key);
441 Py_DECREF(value);
442 if (err < 0)
443 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 self->ufd_uptodate = 0;
446
447 Py_INCREF(Py_None);
448 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000449}
450
451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000452PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000453"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000454Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455
456static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 PyObject *key;
460 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 fd = PyObject_AsFileDescriptor( o );
463 if (fd == -1)
464 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 /* Check whether the fd is already in the array */
467 key = PyLong_FromLong(fd);
468 if (key == NULL)
469 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 if (PyDict_DelItem(self->dict, key) == -1) {
472 Py_DECREF(key);
473 /* This will simply raise the KeyError set by PyDict_DelItem
474 if the file descriptor isn't registered. */
475 return NULL;
476 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 Py_DECREF(key);
479 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 Py_INCREF(Py_None);
482 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483}
484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
487Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489
490static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 PyObject *result_list = NULL, *tout = NULL;
494 int timeout = 0, poll_result, i, j;
495 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
498 return NULL;
499 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 /* Check values for timeout */
502 if (tout == NULL || tout == Py_None)
503 timeout = -1;
504 else if (!PyNumber_Check(tout)) {
505 PyErr_SetString(PyExc_TypeError,
506 "timeout must be an integer or None");
507 return NULL;
508 }
509 else {
510 tout = PyNumber_Long(tout);
511 if (!tout)
512 return NULL;
513 timeout = PyLong_AsLong(tout);
514 Py_DECREF(tout);
515 if (timeout == -1 && PyErr_Occurred())
516 return NULL;
517 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 /* Ensure the ufd array is up to date */
520 if (!self->ufd_uptodate)
521 if (update_ufd_array(self) == 0)
522 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 /* call poll() */
525 Py_BEGIN_ALLOW_THREADS
526 poll_result = poll(self->ufds, self->ufd_len, timeout);
527 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 if (poll_result < 0) {
530 PyErr_SetFromErrno(SelectError);
531 return NULL;
532 }
533
534 /* build the result list */
535
536 result_list = PyList_New(poll_result);
537 if (!result_list)
538 return NULL;
539 else {
540 for (i = 0, j = 0; j < poll_result; j++) {
541 /* skip to the next fired descriptor */
542 while (!self->ufds[i].revents) {
543 i++;
544 }
545 /* if we hit a NULL return, set value to NULL
546 and break out of loop; code at end will
547 clean up result_list */
548 value = PyTuple_New(2);
549 if (value == NULL)
550 goto error;
551 num = PyLong_FromLong(self->ufds[i].fd);
552 if (num == NULL) {
553 Py_DECREF(value);
554 goto error;
555 }
556 PyTuple_SET_ITEM(value, 0, num);
557
558 /* The &0xffff is a workaround for AIX. 'revents'
559 is a 16-bit short, and IBM assigned POLLNVAL
560 to be 0x8000, so the conversion to int results
561 in a negative number. See SF bug #923315. */
562 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
563 if (num == NULL) {
564 Py_DECREF(value);
565 goto error;
566 }
567 PyTuple_SET_ITEM(value, 1, num);
568 if ((PyList_SetItem(result_list, j, value)) == -1) {
569 Py_DECREF(value);
570 goto error;
571 }
572 i++;
573 }
574 }
575 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000576
577 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 Py_DECREF(result_list);
579 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000580}
581
582static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 {"register", (PyCFunction)poll_register,
584 METH_VARARGS, poll_register_doc},
585 {"modify", (PyCFunction)poll_modify,
586 METH_VARARGS, poll_modify_doc},
587 {"unregister", (PyCFunction)poll_unregister,
588 METH_O, poll_unregister_doc},
589 {"poll", (PyCFunction)poll_poll,
590 METH_VARARGS, poll_poll_doc},
591 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000592};
593
594static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000595newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 pollObject *self;
598 self = PyObject_New(pollObject, &poll_Type);
599 if (self == NULL)
600 return NULL;
601 /* ufd_uptodate is a Boolean, denoting whether the
602 array pointed to by ufds matches the contents of the dictionary. */
603 self->ufd_uptodate = 0;
604 self->ufds = NULL;
605 self->dict = PyDict_New();
606 if (self->dict == NULL) {
607 Py_DECREF(self);
608 return NULL;
609 }
610 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000611}
612
613static void
614poll_dealloc(pollObject *self)
615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 if (self->ufds != NULL)
617 PyMem_DEL(self->ufds);
618 Py_XDECREF(self->dict);
619 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000620}
621
Tim Peters0c322792002-07-17 16:49:03 +0000622static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 /* The ob_type field must be initialized in the module init function
624 * to be portable to Windows without using C++. */
625 PyVarObject_HEAD_INIT(NULL, 0)
626 "select.poll", /*tp_name*/
627 sizeof(pollObject), /*tp_basicsize*/
628 0, /*tp_itemsize*/
629 /* methods */
630 (destructor)poll_dealloc, /*tp_dealloc*/
631 0, /*tp_print*/
632 0, /*tp_getattr*/
633 0, /*tp_setattr*/
634 0, /*tp_reserved*/
635 0, /*tp_repr*/
636 0, /*tp_as_number*/
637 0, /*tp_as_sequence*/
638 0, /*tp_as_mapping*/
639 0, /*tp_hash*/
640 0, /*tp_call*/
641 0, /*tp_str*/
642 0, /*tp_getattro*/
643 0, /*tp_setattro*/
644 0, /*tp_as_buffer*/
645 Py_TPFLAGS_DEFAULT, /*tp_flags*/
646 0, /*tp_doc*/
647 0, /*tp_traverse*/
648 0, /*tp_clear*/
649 0, /*tp_richcompare*/
650 0, /*tp_weaklistoffset*/
651 0, /*tp_iter*/
652 0, /*tp_iternext*/
653 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654};
655
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000656PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000658unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659
660static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000661select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000664}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665
666#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000668 * On some systems poll() sets errno on invalid file descriptors. We test
669 * for this at runtime because this bug may be fixed or introduced between
670 * OS releases.
671 */
672static int select_have_broken_poll(void)
673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 int poll_test;
675 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 /* Create a file descriptor to make invalid */
680 if (pipe(filedes) < 0) {
681 return 1;
682 }
683 poll_struct.fd = filedes[0];
684 close(filedes[0]);
685 close(filedes[1]);
686 poll_test = poll(&poll_struct, 1, 0);
687 if (poll_test < 0) {
688 return 1;
689 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
690 return 1;
691 }
692 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693}
694#endif /* __APPLE__ */
695
696#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000697
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000698#ifdef HAVE_EPOLL
699/* **************************************************************************
700 * epoll interface for Linux 2.6
701 *
702 * Written by Christian Heimes
703 * Inspired by Twisted's _epoll.pyx and select.poll()
704 */
705
706#ifdef HAVE_SYS_EPOLL_H
707#include <sys/epoll.h>
708#endif
709
710typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 PyObject_HEAD
712 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000713} pyEpoll_Object;
714
715static PyTypeObject pyEpoll_Type;
716#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
717
718static PyObject *
719pyepoll_err_closed(void)
720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
722 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000723}
724
725static int
726pyepoll_internal_close(pyEpoll_Object *self)
727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 int save_errno = 0;
729 if (self->epfd >= 0) {
730 int epfd = self->epfd;
731 self->epfd = -1;
732 Py_BEGIN_ALLOW_THREADS
733 if (close(epfd) < 0)
734 save_errno = errno;
735 Py_END_ALLOW_THREADS
736 }
737 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000738}
739
740static PyObject *
741newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 if (sizehint == -1) {
746 sizehint = FD_SETSIZE-1;
747 }
748 else if (sizehint < 1) {
749 PyErr_Format(PyExc_ValueError,
750 "sizehint must be greater zero, got %d",
751 sizehint);
752 return NULL;
753 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 assert(type != NULL && type->tp_alloc != NULL);
756 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
757 if (self == NULL)
758 return NULL;
759
760 if (fd == -1) {
761 Py_BEGIN_ALLOW_THREADS
762 self->epfd = epoll_create(sizehint);
763 Py_END_ALLOW_THREADS
764 }
765 else {
766 self->epfd = fd;
767 }
768 if (self->epfd < 0) {
769 Py_DECREF(self);
770 PyErr_SetFromErrno(PyExc_IOError);
771 return NULL;
772 }
773 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000774}
775
776
777static PyObject *
778pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 int sizehint = -1;
781 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
784 &sizehint))
785 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000788}
789
790
791static void
792pyepoll_dealloc(pyEpoll_Object *self)
793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 (void)pyepoll_internal_close(self);
795 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000796}
797
798static PyObject*
799pyepoll_close(pyEpoll_Object *self)
800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 errno = pyepoll_internal_close(self);
802 if (errno < 0) {
803 PyErr_SetFromErrno(PyExc_IOError);
804 return NULL;
805 }
806 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000807}
808
809PyDoc_STRVAR(pyepoll_close_doc,
810"close() -> None\n\
811\n\
812Close the epoll control file descriptor. Further operations on the epoll\n\
813object will raise an exception.");
814
815static PyObject*
816pyepoll_get_closed(pyEpoll_Object *self)
817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 if (self->epfd < 0)
819 Py_RETURN_TRUE;
820 else
821 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000822}
823
824static PyObject*
825pyepoll_fileno(pyEpoll_Object *self)
826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 if (self->epfd < 0)
828 return pyepoll_err_closed();
829 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000830}
831
832PyDoc_STRVAR(pyepoll_fileno_doc,
833"fileno() -> int\n\
834\n\
835Return the epoll control file descriptor.");
836
837static PyObject*
838pyepoll_fromfd(PyObject *cls, PyObject *args)
839{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
843 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000846}
847
848PyDoc_STRVAR(pyepoll_fromfd_doc,
849"fromfd(fd) -> epoll\n\
850\n\
851Create an epoll object from a given control fd.");
852
853static PyObject *
854pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 struct epoll_event ev;
857 int result;
858 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 if (epfd < 0)
861 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 fd = PyObject_AsFileDescriptor(pfd);
864 if (fd == -1) {
865 return NULL;
866 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 switch(op) {
869 case EPOLL_CTL_ADD:
870 case EPOLL_CTL_MOD:
871 ev.events = events;
872 ev.data.fd = fd;
873 Py_BEGIN_ALLOW_THREADS
874 result = epoll_ctl(epfd, op, fd, &ev);
875 Py_END_ALLOW_THREADS
876 break;
877 case EPOLL_CTL_DEL:
878 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
879 * operation required a non-NULL pointer in event, even
880 * though this argument is ignored. */
881 Py_BEGIN_ALLOW_THREADS
882 result = epoll_ctl(epfd, op, fd, &ev);
883 if (errno == EBADF) {
884 /* fd already closed */
885 result = 0;
886 errno = 0;
887 }
888 Py_END_ALLOW_THREADS
889 break;
890 default:
891 result = -1;
892 errno = EINVAL;
893 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 if (result < 0) {
896 PyErr_SetFromErrno(PyExc_IOError);
897 return NULL;
898 }
899 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000900}
901
902static PyObject *
903pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
904{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 PyObject *pfd;
906 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
907 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
910 &pfd, &events)) {
911 return NULL;
912 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000915}
916
917PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000918"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000919\n\
Georg Brandl222569d2010-08-02 20:47:56 +0000920Registers a new fd or modifies an already registered fd.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000921fd is the target file descriptor of the operation.\n\
922events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000923is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
924\n\
925The epoll interface supports all file descriptors that support poll.");
926
927static PyObject *
928pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
929{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 PyObject *pfd;
931 unsigned int events;
932 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
935 &pfd, &events)) {
936 return NULL;
937 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000940}
941
942PyDoc_STRVAR(pyepoll_modify_doc,
943"modify(fd, eventmask) -> None\n\
944\n\
945fd is the target file descriptor of the operation\n\
946events is a bit set composed of the various EPOLL constants");
947
948static PyObject *
949pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 PyObject *pfd;
952 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
955 &pfd)) {
956 return NULL;
957 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000960}
961
962PyDoc_STRVAR(pyepoll_unregister_doc,
963"unregister(fd) -> None\n\
964\n\
965fd is the target file descriptor of the operation.");
966
967static PyObject *
968pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 double dtimeout = -1.;
971 int timeout;
972 int maxevents = -1;
973 int nfds, i;
974 PyObject *elist = NULL, *etuple = NULL;
975 struct epoll_event *evs = NULL;
976 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 if (self->epfd < 0)
979 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
982 &dtimeout, &maxevents)) {
983 return NULL;
984 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 if (dtimeout < 0) {
987 timeout = -1;
988 }
989 else if (dtimeout * 1000.0 > INT_MAX) {
990 PyErr_SetString(PyExc_OverflowError,
991 "timeout is too large");
992 return NULL;
993 }
994 else {
995 timeout = (int)(dtimeout * 1000.0);
996 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 if (maxevents == -1) {
999 maxevents = FD_SETSIZE-1;
1000 }
1001 else if (maxevents < 1) {
1002 PyErr_Format(PyExc_ValueError,
1003 "maxevents must be greater than 0, got %d",
1004 maxevents);
1005 return NULL;
1006 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 evs = PyMem_New(struct epoll_event, maxevents);
1009 if (evs == NULL) {
1010 Py_DECREF(self);
1011 PyErr_NoMemory();
1012 return NULL;
1013 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 Py_BEGIN_ALLOW_THREADS
1016 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1017 Py_END_ALLOW_THREADS
1018 if (nfds < 0) {
1019 PyErr_SetFromErrno(PyExc_IOError);
1020 goto error;
1021 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 elist = PyList_New(nfds);
1024 if (elist == NULL) {
1025 goto error;
1026 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 for (i = 0; i < nfds; i++) {
1029 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1030 if (etuple == NULL) {
1031 Py_CLEAR(elist);
1032 goto error;
1033 }
1034 PyList_SET_ITEM(elist, i, etuple);
1035 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001036
Christian Heimesf6cd9672008-03-26 13:45:42 +00001037 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 PyMem_Free(evs);
1039 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001040}
1041
1042PyDoc_STRVAR(pyepoll_poll_doc,
1043"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1044\n\
1045Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1046in seconds (as float). -1 makes poll wait indefinitely.\n\
1047Up to maxevents are returned to the caller.");
1048
1049static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 {"fromfd", (PyCFunction)pyepoll_fromfd,
1051 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1052 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1053 pyepoll_close_doc},
1054 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1055 pyepoll_fileno_doc},
1056 {"modify", (PyCFunction)pyepoll_modify,
1057 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1058 {"register", (PyCFunction)pyepoll_register,
1059 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1060 {"unregister", (PyCFunction)pyepoll_unregister,
1061 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1062 {"poll", (PyCFunction)pyepoll_poll,
1063 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1064 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001065};
1066
1067static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 {"closed", (getter)pyepoll_get_closed, NULL,
1069 "True if the epoll handler is closed"},
1070 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001071};
1072
1073PyDoc_STRVAR(pyepoll_doc,
1074"select.epoll([sizehint=-1])\n\
1075\n\
1076Returns an epolling object\n\
1077\n\
1078sizehint must be a positive integer or -1 for the default size. The\n\
1079sizehint is used to optimize internal data structures. It doesn't limit\n\
1080the maximum number of monitored events.");
1081
1082static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 PyVarObject_HEAD_INIT(NULL, 0)
1084 "select.epoll", /* tp_name */
1085 sizeof(pyEpoll_Object), /* tp_basicsize */
1086 0, /* tp_itemsize */
1087 (destructor)pyepoll_dealloc, /* tp_dealloc */
1088 0, /* tp_print */
1089 0, /* tp_getattr */
1090 0, /* tp_setattr */
1091 0, /* tp_reserved */
1092 0, /* tp_repr */
1093 0, /* tp_as_number */
1094 0, /* tp_as_sequence */
1095 0, /* tp_as_mapping */
1096 0, /* tp_hash */
1097 0, /* tp_call */
1098 0, /* tp_str */
1099 PyObject_GenericGetAttr, /* tp_getattro */
1100 0, /* tp_setattro */
1101 0, /* tp_as_buffer */
1102 Py_TPFLAGS_DEFAULT, /* tp_flags */
1103 pyepoll_doc, /* tp_doc */
1104 0, /* tp_traverse */
1105 0, /* tp_clear */
1106 0, /* tp_richcompare */
1107 0, /* tp_weaklistoffset */
1108 0, /* tp_iter */
1109 0, /* tp_iternext */
1110 pyepoll_methods, /* tp_methods */
1111 0, /* tp_members */
1112 pyepoll_getsetlist, /* tp_getset */
1113 0, /* tp_base */
1114 0, /* tp_dict */
1115 0, /* tp_descr_get */
1116 0, /* tp_descr_set */
1117 0, /* tp_dictoffset */
1118 0, /* tp_init */
1119 0, /* tp_alloc */
1120 pyepoll_new, /* tp_new */
1121 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001122};
1123
1124#endif /* HAVE_EPOLL */
1125
1126#ifdef HAVE_KQUEUE
1127/* **************************************************************************
1128 * kqueue interface for BSD
1129 *
1130 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1131 * All rights reserved.
1132 *
1133 * Redistribution and use in source and binary forms, with or without
1134 * modification, are permitted provided that the following conditions
1135 * are met:
1136 * 1. Redistributions of source code must retain the above copyright
1137 * notice, this list of conditions and the following disclaimer.
1138 * 2. Redistributions in binary form must reproduce the above copyright
1139 * notice, this list of conditions and the following disclaimer in the
1140 * documentation and/or other materials provided with the distribution.
1141 *
1142 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1143 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1144 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1145 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1146 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1147 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1148 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1149 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1150 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1151 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1152 * SUCH DAMAGE.
1153 */
1154
1155#ifdef HAVE_SYS_EVENT_H
1156#include <sys/event.h>
1157#endif
1158
1159PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001160"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001161\n\
1162This object is the equivalent of the struct kevent for the C API.\n\
1163\n\
1164See the kqueue manpage for more detailed information about the meaning\n\
1165of the arguments.\n\
1166\n\
1167One minor note: while you might hope that udata could store a\n\
1168reference to a python object, it cannot, because it is impossible to\n\
1169keep a proper reference count of the object once it's passed into the\n\
1170kernel. Therefore, I have restricted it to only storing an integer. I\n\
1171recommend ignoring it and simply using the 'ident' field to key off\n\
1172of. You could also set up a dictionary on the python side to store a\n\
1173udata->object mapping.");
1174
1175typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 PyObject_HEAD
1177 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001178} kqueue_event_Object;
1179
1180static PyTypeObject kqueue_event_Type;
1181
1182#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1183
1184typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 PyObject_HEAD
1186 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001187} kqueue_queue_Object;
1188
1189static PyTypeObject kqueue_queue_Type;
1190
1191#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1192
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001193#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1194# error uintptr_t does not match void *!
1195#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1196# define T_UINTPTRT T_ULONGLONG
1197# define T_INTPTRT T_LONGLONG
1198# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1199# define UINTPTRT_FMT_UNIT "K"
1200# define INTPTRT_FMT_UNIT "L"
1201#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1202# define T_UINTPTRT T_ULONG
1203# define T_INTPTRT T_LONG
1204# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1205# define UINTPTRT_FMT_UNIT "k"
1206# define INTPTRT_FMT_UNIT "l"
1207#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1208# define T_UINTPTRT T_UINT
1209# define T_INTPTRT T_INT
1210# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1211# define UINTPTRT_FMT_UNIT "I"
1212# define INTPTRT_FMT_UNIT "i"
1213#else
1214# error uintptr_t does not match int, long, or long long!
1215#endif
1216
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001217/* Unfortunately, we can't store python objects in udata, because
1218 * kevents in the kernel can be removed without warning, which would
1219 * forever lose the refcount on the object stored with it.
1220 */
1221
1222#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1223static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1225 {"filter", T_SHORT, KQ_OFF(e.filter)},
1226 {"flags", T_USHORT, KQ_OFF(e.flags)},
1227 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1228 {"data", T_INTPTRT, KQ_OFF(e.data)},
1229 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1230 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231};
1232#undef KQ_OFF
1233
1234static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001235
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001236kqueue_event_repr(kqueue_event_Object *s)
1237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 char buf[1024];
1239 PyOS_snprintf(
1240 buf, sizeof(buf),
1241 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1242 "data=0x%zd udata=%p>",
1243 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1244 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1245 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001246}
1247
1248static int
1249kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 PyObject *pfd;
1252 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1253 "data", "udata", NULL};
1254 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1259 &pfd, &(self->e.filter), &(self->e.flags),
1260 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1261 return -1;
1262 }
1263
1264 if (PyLong_Check(pfd)) {
1265 self->e.ident = PyLong_AsUintptr_t(pfd);
1266 }
1267 else {
1268 self->e.ident = PyObject_AsFileDescriptor(pfd);
1269 }
1270 if (PyErr_Occurred()) {
1271 return -1;
1272 }
1273 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001274}
1275
1276static PyObject *
1277kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 if (!kqueue_event_Check(o)) {
1283 if (op == Py_EQ || op == Py_NE) {
1284 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1285 Py_INCREF(res);
1286 return res;
1287 }
1288 PyErr_Format(PyExc_TypeError,
1289 "can't compare %.200s to %.200s",
1290 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1291 return NULL;
1292 }
1293 if (((result = s->e.ident - o->e.ident) == 0) &&
1294 ((result = s->e.filter - o->e.filter) == 0) &&
1295 ((result = s->e.flags - o->e.flags) == 0) &&
1296 ((result = s->e.fflags - o->e.fflags) == 0) &&
1297 ((result = s->e.data - o->e.data) == 0) &&
1298 ((result = s->e.udata - o->e.udata) == 0)
1299 ) {
1300 result = 0;
1301 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 switch (op) {
1304 case Py_EQ:
1305 result = (result == 0);
1306 break;
1307 case Py_NE:
1308 result = (result != 0);
1309 break;
1310 case Py_LE:
1311 result = (result <= 0);
1312 break;
1313 case Py_GE:
1314 result = (result >= 0);
1315 break;
1316 case Py_LT:
1317 result = (result < 0);
1318 break;
1319 case Py_GT:
1320 result = (result > 0);
1321 break;
1322 }
1323 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001324}
1325
1326static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 PyVarObject_HEAD_INIT(NULL, 0)
1328 "select.kevent", /* tp_name */
1329 sizeof(kqueue_event_Object), /* tp_basicsize */
1330 0, /* tp_itemsize */
1331 0, /* tp_dealloc */
1332 0, /* tp_print */
1333 0, /* tp_getattr */
1334 0, /* tp_setattr */
1335 0, /* tp_reserved */
1336 (reprfunc)kqueue_event_repr, /* tp_repr */
1337 0, /* tp_as_number */
1338 0, /* tp_as_sequence */
1339 0, /* tp_as_mapping */
1340 0, /* tp_hash */
1341 0, /* tp_call */
1342 0, /* tp_str */
1343 0, /* tp_getattro */
1344 0, /* tp_setattro */
1345 0, /* tp_as_buffer */
1346 Py_TPFLAGS_DEFAULT, /* tp_flags */
1347 kqueue_event_doc, /* tp_doc */
1348 0, /* tp_traverse */
1349 0, /* tp_clear */
1350 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1351 0, /* tp_weaklistoffset */
1352 0, /* tp_iter */
1353 0, /* tp_iternext */
1354 0, /* tp_methods */
1355 kqueue_event_members, /* tp_members */
1356 0, /* tp_getset */
1357 0, /* tp_base */
1358 0, /* tp_dict */
1359 0, /* tp_descr_get */
1360 0, /* tp_descr_set */
1361 0, /* tp_dictoffset */
1362 (initproc)kqueue_event_init, /* tp_init */
1363 0, /* tp_alloc */
1364 0, /* tp_new */
1365 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001366};
1367
1368static PyObject *
1369kqueue_queue_err_closed(void)
1370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1372 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001373}
1374
1375static int
1376kqueue_queue_internal_close(kqueue_queue_Object *self)
1377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 int save_errno = 0;
1379 if (self->kqfd >= 0) {
1380 int kqfd = self->kqfd;
1381 self->kqfd = -1;
1382 Py_BEGIN_ALLOW_THREADS
1383 if (close(kqfd) < 0)
1384 save_errno = errno;
1385 Py_END_ALLOW_THREADS
1386 }
1387 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388}
1389
1390static PyObject *
1391newKqueue_Object(PyTypeObject *type, SOCKET fd)
1392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 kqueue_queue_Object *self;
1394 assert(type != NULL && type->tp_alloc != NULL);
1395 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1396 if (self == NULL) {
1397 return NULL;
1398 }
1399
1400 if (fd == -1) {
1401 Py_BEGIN_ALLOW_THREADS
1402 self->kqfd = kqueue();
1403 Py_END_ALLOW_THREADS
1404 }
1405 else {
1406 self->kqfd = fd;
1407 }
1408 if (self->kqfd < 0) {
1409 Py_DECREF(self);
1410 PyErr_SetFromErrno(PyExc_IOError);
1411 return NULL;
1412 }
1413 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001414}
1415
1416static PyObject *
1417kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1418{
1419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if ((args != NULL && PyObject_Size(args)) ||
1421 (kwds != NULL && PyObject_Size(kwds))) {
1422 PyErr_SetString(PyExc_ValueError,
1423 "select.kqueue doesn't accept arguments");
1424 return NULL;
1425 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428}
1429
1430static void
1431kqueue_queue_dealloc(kqueue_queue_Object *self)
1432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 kqueue_queue_internal_close(self);
1434 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001435}
1436
1437static PyObject*
1438kqueue_queue_close(kqueue_queue_Object *self)
1439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 errno = kqueue_queue_internal_close(self);
1441 if (errno < 0) {
1442 PyErr_SetFromErrno(PyExc_IOError);
1443 return NULL;
1444 }
1445 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446}
1447
1448PyDoc_STRVAR(kqueue_queue_close_doc,
1449"close() -> None\n\
1450\n\
1451Close the kqueue control file descriptor. Further operations on the kqueue\n\
1452object will raise an exception.");
1453
1454static PyObject*
1455kqueue_queue_get_closed(kqueue_queue_Object *self)
1456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 if (self->kqfd < 0)
1458 Py_RETURN_TRUE;
1459 else
1460 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461}
1462
1463static PyObject*
1464kqueue_queue_fileno(kqueue_queue_Object *self)
1465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 if (self->kqfd < 0)
1467 return kqueue_queue_err_closed();
1468 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001469}
1470
1471PyDoc_STRVAR(kqueue_queue_fileno_doc,
1472"fileno() -> int\n\
1473\n\
1474Return the kqueue control file descriptor.");
1475
1476static PyObject*
1477kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1482 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001485}
1486
1487PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1488"fromfd(fd) -> kqueue\n\
1489\n\
1490Create a kqueue object from a given control fd.");
1491
1492static PyObject *
1493kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 int nevents = 0;
1496 int gotevents = 0;
1497 int nchanges = 0;
1498 int i = 0;
1499 PyObject *otimeout = NULL;
1500 PyObject *ch = NULL;
1501 PyObject *it = NULL, *ei = NULL;
1502 PyObject *result = NULL;
1503 struct kevent *evl = NULL;
1504 struct kevent *chl = NULL;
1505 struct timespec timeoutspec;
1506 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 if (self->kqfd < 0)
1509 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1512 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 if (nevents < 0) {
1515 PyErr_Format(PyExc_ValueError,
1516 "Length of eventlist must be 0 or positive, got %d",
1517 nevents);
1518 return NULL;
1519 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 if (otimeout == Py_None || otimeout == NULL) {
1522 ptimeoutspec = NULL;
1523 }
1524 else if (PyNumber_Check(otimeout)) {
1525 double timeout;
1526 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 timeout = PyFloat_AsDouble(otimeout);
1529 if (timeout == -1 && PyErr_Occurred())
1530 return NULL;
1531 if (timeout > (double)LONG_MAX) {
1532 PyErr_SetString(PyExc_OverflowError,
1533 "timeout period too long");
1534 return NULL;
1535 }
1536 if (timeout < 0) {
1537 PyErr_SetString(PyExc_ValueError,
1538 "timeout must be positive or None");
1539 return NULL;
1540 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 seconds = (long)timeout;
1543 timeout = timeout - (double)seconds;
1544 timeoutspec.tv_sec = seconds;
1545 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1546 ptimeoutspec = &timeoutspec;
1547 }
1548 else {
1549 PyErr_Format(PyExc_TypeError,
1550 "timeout argument must be an number "
1551 "or None, got %.200s",
1552 Py_TYPE(otimeout)->tp_name);
1553 return NULL;
1554 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 if (ch != NULL && ch != Py_None) {
1557 it = PyObject_GetIter(ch);
1558 if (it == NULL) {
1559 PyErr_SetString(PyExc_TypeError,
1560 "changelist is not iterable");
1561 return NULL;
1562 }
1563 nchanges = PyObject_Size(ch);
1564 if (nchanges < 0) {
1565 goto error;
1566 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 chl = PyMem_New(struct kevent, nchanges);
1569 if (chl == NULL) {
1570 PyErr_NoMemory();
1571 goto error;
1572 }
1573 i = 0;
1574 while ((ei = PyIter_Next(it)) != NULL) {
1575 if (!kqueue_event_Check(ei)) {
1576 Py_DECREF(ei);
1577 PyErr_SetString(PyExc_TypeError,
1578 "changelist must be an iterable of "
1579 "select.kevent objects");
1580 goto error;
1581 } else {
1582 chl[i++] = ((kqueue_event_Object *)ei)->e;
1583 }
1584 Py_DECREF(ei);
1585 }
1586 }
1587 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 /* event list */
1590 if (nevents) {
1591 evl = PyMem_New(struct kevent, nevents);
1592 if (evl == NULL) {
1593 PyErr_NoMemory();
1594 goto error;
1595 }
1596 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 Py_BEGIN_ALLOW_THREADS
1599 gotevents = kevent(self->kqfd, chl, nchanges,
1600 evl, nevents, ptimeoutspec);
1601 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 if (gotevents == -1) {
1604 PyErr_SetFromErrno(PyExc_OSError);
1605 goto error;
1606 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 result = PyList_New(gotevents);
1609 if (result == NULL) {
1610 goto error;
1611 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 for (i = 0; i < gotevents; i++) {
1614 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1617 if (ch == NULL) {
1618 goto error;
1619 }
1620 ch->e = evl[i];
1621 PyList_SET_ITEM(result, i, (PyObject *)ch);
1622 }
1623 PyMem_Free(chl);
1624 PyMem_Free(evl);
1625 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001626
1627 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 PyMem_Free(chl);
1629 PyMem_Free(evl);
1630 Py_XDECREF(result);
1631 Py_XDECREF(it);
1632 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001633}
1634
1635PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001636"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001637\n\
1638Calls the kernel kevent function.\n\
1639- changelist must be a list of kevent objects describing the changes\n\
1640 to be made to the kernel's watch list or None.\n\
1641- max_events lets you specify the maximum number of events that the\n\
1642 kernel will return.\n\
1643- timeout is the maximum time to wait in seconds, or else None,\n\
1644 to wait forever. timeout accepts floats for smaller timeouts, too.");
1645
1646
1647static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1649 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1650 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1651 kqueue_queue_close_doc},
1652 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1653 kqueue_queue_fileno_doc},
1654 {"control", (PyCFunction)kqueue_queue_control,
1655 METH_VARARGS , kqueue_queue_control_doc},
1656 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001657};
1658
1659static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 {"closed", (getter)kqueue_queue_get_closed, NULL,
1661 "True if the kqueue handler is closed"},
1662 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001663};
1664
1665PyDoc_STRVAR(kqueue_queue_doc,
1666"Kqueue syscall wrapper.\n\
1667\n\
1668For example, to start watching a socket for input:\n\
1669>>> kq = kqueue()\n\
1670>>> sock = socket()\n\
1671>>> sock.connect((host, port))\n\
1672>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1673\n\
1674To wait one second for it to become writeable:\n\
1675>>> kq.control(None, 1, 1000)\n\
1676\n\
1677To stop listening:\n\
1678>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1679
1680static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 PyVarObject_HEAD_INIT(NULL, 0)
1682 "select.kqueue", /* tp_name */
1683 sizeof(kqueue_queue_Object), /* tp_basicsize */
1684 0, /* tp_itemsize */
1685 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1686 0, /* tp_print */
1687 0, /* tp_getattr */
1688 0, /* tp_setattr */
1689 0, /* tp_reserved */
1690 0, /* tp_repr */
1691 0, /* tp_as_number */
1692 0, /* tp_as_sequence */
1693 0, /* tp_as_mapping */
1694 0, /* tp_hash */
1695 0, /* tp_call */
1696 0, /* tp_str */
1697 0, /* tp_getattro */
1698 0, /* tp_setattro */
1699 0, /* tp_as_buffer */
1700 Py_TPFLAGS_DEFAULT, /* tp_flags */
1701 kqueue_queue_doc, /* tp_doc */
1702 0, /* tp_traverse */
1703 0, /* tp_clear */
1704 0, /* tp_richcompare */
1705 0, /* tp_weaklistoffset */
1706 0, /* tp_iter */
1707 0, /* tp_iternext */
1708 kqueue_queue_methods, /* tp_methods */
1709 0, /* tp_members */
1710 kqueue_queue_getsetlist, /* tp_getset */
1711 0, /* tp_base */
1712 0, /* tp_dict */
1713 0, /* tp_descr_get */
1714 0, /* tp_descr_set */
1715 0, /* tp_dictoffset */
1716 0, /* tp_init */
1717 0, /* tp_alloc */
1718 kqueue_queue_new, /* tp_new */
1719 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001720};
1721
1722#endif /* HAVE_KQUEUE */
1723/* ************************************************************************ */
1724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001725PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001726"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1727\n\
1728Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001729The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001730rlist -- wait until ready for reading\n\
1731wlist -- wait until ready for writing\n\
1732xlist -- wait for an ``exceptional condition''\n\
1733If only one kind of condition is required, pass [] for the other lists.\n\
1734A file descriptor is either a socket or file object, or a small integer\n\
1735gotten from a fileno() method call on one of those.\n\
1736\n\
1737The optional 4th argument specifies a timeout in seconds; it may be\n\
1738a floating point number to specify fractions of seconds. If it is absent\n\
1739or None, the call will never time out.\n\
1740\n\
1741The return value is a tuple of three lists corresponding to the first three\n\
1742arguments; each contains the subset of the corresponding file descriptors\n\
1743that are ready.\n\
1744\n\
1745*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001746On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001747descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001748
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001749static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001751#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001753#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001755};
1756
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001757PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001758"This module supports asynchronous I/O on multiple file descriptors.\n\
1759\n\
1760*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001761On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001762
Martin v. Löwis1a214512008-06-11 05:26:20 +00001763
1764static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 PyModuleDef_HEAD_INIT,
1766 "select",
1767 module_doc,
1768 -1,
1769 select_methods,
1770 NULL,
1771 NULL,
1772 NULL,
1773 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001774};
1775
Mark Hammond62b1ab12002-07-23 06:31:15 +00001776PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001777PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 PyObject *m;
1780 m = PyModule_Create(&selectmodule);
1781 if (m == NULL)
1782 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 SelectError = PyErr_NewException("select.error", NULL, NULL);
1785 Py_INCREF(SelectError);
1786 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001787
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001788#ifdef PIPE_BUF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001790#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001791
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001792#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001793#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 if (select_have_broken_poll()) {
1795 if (PyObject_DelAttrString(m, "poll") == -1) {
1796 PyErr_Clear();
1797 }
1798 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001799#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001801#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 if (PyType_Ready(&poll_Type) < 0)
1803 return NULL;
1804 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1805 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1806 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1807 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1808 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1809 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001810
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001811#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001813#endif
1814#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001816#endif
1817#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001819#endif
1820#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001822#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001823#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001825#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001828
1829#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1831 if (PyType_Ready(&pyEpoll_Type) < 0)
1832 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 Py_INCREF(&pyEpoll_Type);
1835 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1838 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1839 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1840 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1841 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1842 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001843#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 /* Kernel 2.6.2+ */
1845 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001846#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1848 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1849 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1850 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1851 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1852 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853#endif /* HAVE_EPOLL */
1854
1855#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 kqueue_event_Type.tp_new = PyType_GenericNew;
1857 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1858 if(PyType_Ready(&kqueue_event_Type) < 0)
1859 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 Py_INCREF(&kqueue_event_Type);
1862 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1865 if(PyType_Ready(&kqueue_queue_Type) < 0)
1866 return NULL;
1867 Py_INCREF(&kqueue_queue_Type);
1868 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1869
1870 /* event filters */
1871 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1872 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1873 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1874 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1875 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001878#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1880 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 /* event flags */
1883 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1884 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1885 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1886 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1887 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1888 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1891 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1894 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 /* READ WRITE filter flag */
1897 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 /* VNODE filter flags */
1900 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1903 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 /* PROC filter flags */
1909 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1910 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1916 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1917 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1918
1919 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001920#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1922 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1923 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001924#endif
1925
1926#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001928}