blob: 5a8580c8ac92381ed367ba9bd0013f9dd1be2e37 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Christian Heimes0e9ab5f2008-03-21 23:49:44 +000010#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000011
Ronald Oussoren32fd16e2006-04-23 12:36:23 +000012#ifdef __APPLE__
13 /* Perform runtime testing for a broken poll on OSX to make it easier
14 * to use the same binary on multiple releases of the OS.
15 */
16#undef HAVE_BROKEN_POLL
17#endif
18
Tim Petersd92dfe02000-12-12 01:18:41 +000019/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
20 64 is too small (too many people have bumped into that limit).
21 Here we boost it.
22 Users who want even more than the boosted limit should #define
23 FD_SETSIZE higher before this; e.g., via compiler /D switch.
24*/
25#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
26#define FD_SETSIZE 512
Antoine Pitrouc83ea132010-05-09 14:46:46 +000027#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000028
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000030#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000031#elif defined(HAVE_SYS_POLL_H)
32#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000033#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000034
Guido van Rossum37273171996-12-09 18:47:43 +000035#ifdef __sgi
36/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000037extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000038#endif
39
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000040#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000042#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000044#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#include <sys/time.h>
46#include <utils.h>
47#endif
48
Guido van Rossum6f489d91996-06-28 20:15:15 +000049#ifdef MS_WINDOWS
Kristján Valur Jónssonf6f3c4a2010-11-03 13:27:33 +000050# include <winsock2.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051#else
Neal Norwitz2a30cd02006-07-10 01:18:57 +000052# define SOCKET int
53# ifdef __BEOS__
54# include <net/socket.h>
55# elif defined(__VMS)
56# include <socket.h>
57# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000058#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000059
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000060static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000061
Barry Warsawc1cb3601996-12-12 22:16:21 +000062/* list of Python objects and their file descriptor */
63typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000064 PyObject *obj; /* owned reference */
65 SOCKET fd;
66 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000067} pylist;
68
Barry Warsawc1cb3601996-12-12 22:16:21 +000069static void
Tim Peters4b046c22001-08-16 21:59:46 +000070reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000071{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000072 int i;
73 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
74 Py_XDECREF(fd2obj[i].obj);
75 fd2obj[i].obj = NULL;
76 }
77 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000078}
79
80
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000081/* returns -1 and sets the Python exception if an error occurred, otherwise
82 returns a number >= 0
83*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000084static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000085seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000086{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000087 int i;
88 int max = -1;
89 int index = 0;
90 int len = -1;
91 PyObject* fast_seq = NULL;
92 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000093
Antoine Pitrouc83ea132010-05-09 14:46:46 +000094 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
95 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000096
Antoine Pitrouc83ea132010-05-09 14:46:46 +000097 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
98 if (!fast_seq)
99 return -1;
100
101 len = PySequence_Fast_GET_SIZE(fast_seq);
102
103 for (i = 0; i < len; i++) {
104 SOCKET v;
105
106 /* any intervening fileno() calls could decr this refcnt */
107 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000108 return -1;
109
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000110 Py_INCREF(o);
111 v = PyObject_AsFileDescriptor( o );
112 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000114#if defined(_MSC_VER)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000116#else /* !_MSC_VER */
Charles-François Natalifda7b372011-08-28 16:22:33 +0200117 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000118 PyErr_SetString(PyExc_ValueError,
119 "filedescriptor out of range in select()");
120 goto finally;
121 }
122 if (v > max)
123 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000124#endif /* _MSC_VER */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000125 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000127 /* add object and its file descriptor to the list */
128 if (index >= FD_SETSIZE) {
129 PyErr_SetString(PyExc_ValueError,
130 "too many file descriptors in select()");
131 goto finally;
132 }
133 fd2obj[index].obj = o;
134 fd2obj[index].fd = v;
135 fd2obj[index].sentinel = 0;
136 fd2obj[++index].sentinel = -1;
137 }
138 Py_DECREF(fast_seq);
139 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000140
141 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000142 Py_XDECREF(o);
143 Py_DECREF(fast_seq);
144 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000145}
146
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000147/* returns NULL and sets the Python exception if an error occurred */
148static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000149set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000150{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000151 int i, j, count=0;
152 PyObject *list, *o;
153 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000154
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000155 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
156 if (FD_ISSET(fd2obj[j].fd, set))
157 count++;
158 }
159 list = PyList_New(count);
160 if (!list)
161 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000162
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000163 i = 0;
164 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
165 fd = fd2obj[j].fd;
166 if (FD_ISSET(fd, set)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000167 o = fd2obj[j].obj;
168 fd2obj[j].obj = NULL;
169 /* transfer ownership */
170 if (PyList_SetItem(list, i, o) < 0)
171 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000173 i++;
174 }
175 }
176 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000178 Py_DECREF(list);
179 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000180}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000181
Barry Warsawb44740f2001-08-16 16:52:59 +0000182#undef SELECT_USES_HEAP
183#if FD_SETSIZE > 1024
184#define SELECT_USES_HEAP
185#endif /* FD_SETSIZE > 1024 */
186
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000187static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000188select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000189{
Barry Warsawb44740f2001-08-16 16:52:59 +0000190#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000191 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#else /* !SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000193 /* XXX: All this should probably be implemented as follows:
194 * - find the highest descriptor we're interested in
195 * - add one
196 * - that's the size
197 * See: Stevens, APitUE, $12.5.1
198 */
199 pylist rfd2obj[FD_SETSIZE + 1];
200 pylist wfd2obj[FD_SETSIZE + 1];
201 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000202#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000203 PyObject *ifdlist, *ofdlist, *efdlist;
204 PyObject *ret = NULL;
205 PyObject *tout = Py_None;
206 fd_set ifdset, ofdset, efdset;
207 double timeout;
208 struct timeval tv, *tvp;
209 long seconds;
210 int imax, omax, emax, max;
211 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000213 /* convert arguments */
214 if (!PyArg_UnpackTuple(args, "select", 3, 4,
215 &ifdlist, &ofdlist, &efdlist, &tout))
216 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000217
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000218 if (tout == Py_None)
219 tvp = (struct timeval *)0;
220 else if (!PyNumber_Check(tout)) {
221 PyErr_SetString(PyExc_TypeError,
222 "timeout must be a float or None");
223 return NULL;
224 }
225 else {
226 timeout = PyFloat_AsDouble(tout);
227 if (timeout == -1 && PyErr_Occurred())
228 return NULL;
229 if (timeout > (double)LONG_MAX) {
230 PyErr_SetString(PyExc_OverflowError,
231 "timeout period too long");
232 return NULL;
233 }
234 seconds = (long)timeout;
235 timeout = timeout - (double)seconds;
236 tv.tv_sec = seconds;
237 tv.tv_usec = (long)(timeout * 1E6);
238 tvp = &tv;
239 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000240
Guido van Rossumed233a51992-06-23 09:07:03 +0000241
Barry Warsawb44740f2001-08-16 16:52:59 +0000242#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000243 /* Allocate memory for the lists */
244 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
245 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
246 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
247 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
248 if (rfd2obj) PyMem_DEL(rfd2obj);
249 if (wfd2obj) PyMem_DEL(wfd2obj);
250 if (efd2obj) PyMem_DEL(efd2obj);
251 return PyErr_NoMemory();
252 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000253#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000254 /* Convert sequences to fd_sets, and get maximum fd number
255 * propagates the Python exception set in seq2set()
256 */
257 rfd2obj[0].sentinel = -1;
258 wfd2obj[0].sentinel = -1;
259 efd2obj[0].sentinel = -1;
260 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
261 goto finally;
262 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
263 goto finally;
264 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
265 goto finally;
266 max = imax;
267 if (omax > max) max = omax;
268 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000269
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000270 Py_BEGIN_ALLOW_THREADS
271 n = select(max, &ifdset, &ofdset, &efdset, tvp);
272 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000273
Thomas Heller106f4c72002-09-24 16:51:00 +0000274#ifdef MS_WINDOWS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000275 if (n == SOCKET_ERROR) {
276 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
277 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000278#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279 if (n < 0) {
280 PyErr_SetFromErrno(SelectError);
281 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000282#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000283 else {
284 /* any of these three calls can raise an exception. it's more
285 convenient to test for this after all three calls... but
286 is that acceptable?
287 */
288 ifdlist = set2list(&ifdset, rfd2obj);
289 ofdlist = set2list(&ofdset, wfd2obj);
290 efdlist = set2list(&efdset, efd2obj);
291 if (PyErr_Occurred())
292 ret = NULL;
293 else
294 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000295
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000296 Py_DECREF(ifdlist);
297 Py_DECREF(ofdlist);
298 Py_DECREF(efdlist);
299 }
300
Barry Warsawc1cb3601996-12-12 22:16:21 +0000301 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000302 reap_obj(rfd2obj);
303 reap_obj(wfd2obj);
304 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000305#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000306 PyMem_DEL(rfd2obj);
307 PyMem_DEL(wfd2obj);
308 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000309#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000310 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000311}
312
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000313#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000314/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000315 * poll() support
316 */
317
318typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000319 PyObject_HEAD
320 PyObject *dict;
321 int ufd_uptodate;
322 int ufd_len;
323 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000324} pollObject;
325
Jeremy Hylton938ace62002-07-17 16:30:39 +0000326static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000327
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000328/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000329 contained within a pollObject. Return 1 on success, 0 on an error.
330*/
331
332static int
333update_ufd_array(pollObject *self)
334{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000335 Py_ssize_t i, pos;
336 PyObject *key, *value;
337 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000338
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000339 self->ufd_len = PyDict_Size(self->dict);
340 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
341 if (self->ufds == NULL) {
342 self->ufds = old_ufds;
343 PyErr_NoMemory();
344 return 0;
345 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000347 i = pos = 0;
348 while (PyDict_Next(self->dict, &pos, &key, &value)) {
349 self->ufds[i].fd = PyInt_AsLong(key);
350 self->ufds[i].events = (short)PyInt_AsLong(value);
351 i++;
352 }
353 self->ufd_uptodate = 1;
354 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000355}
356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000357PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000358"register(fd [, eventmask] ) -> None\n\n\
359Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000360fd -- either an integer, or an object with a fileno() method returning an\n\
361 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000362events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363
364static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000365poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000367 PyObject *o, *key, *value;
368 int fd, events = POLLIN | POLLPRI | POLLOUT;
369 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000371 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
372 return NULL;
373 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000375 fd = PyObject_AsFileDescriptor(o);
376 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000377
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000378 /* Add entry to the internal dictionary: the key is the
379 file descriptor, and the value is the event mask. */
380 key = PyInt_FromLong(fd);
381 if (key == NULL)
382 return NULL;
383 value = PyInt_FromLong(events);
384 if (value == NULL) {
385 Py_DECREF(key);
386 return NULL;
387 }
388 err = PyDict_SetItem(self->dict, key, value);
389 Py_DECREF(key);
390 Py_DECREF(value);
391 if (err < 0)
392 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000393
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000394 self->ufd_uptodate = 0;
395
396 Py_INCREF(Py_None);
397 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000398}
399
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000400PyDoc_STRVAR(poll_modify_doc,
401"modify(fd, eventmask) -> None\n\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000402Modify an already registered file descriptor.\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000403fd -- either an integer, or an object with a fileno() method returning an\n\
404 int.\n\
405events -- an optional bitmask describing the type of events to check for");
406
407static PyObject *
408poll_modify(pollObject *self, PyObject *args)
409{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000410 PyObject *o, *key, *value;
411 int fd, events;
412 int err;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000413
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000414 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
415 return NULL;
416 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000417
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000418 fd = PyObject_AsFileDescriptor(o);
419 if (fd == -1) return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000420
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000421 /* Modify registered fd */
422 key = PyInt_FromLong(fd);
423 if (key == NULL)
424 return NULL;
425 if (PyDict_GetItem(self->dict, key) == NULL) {
426 errno = ENOENT;
427 PyErr_SetFromErrno(PyExc_IOError);
428 return NULL;
429 }
430 value = PyInt_FromLong(events);
431 if (value == NULL) {
432 Py_DECREF(key);
433 return NULL;
434 }
435 err = PyDict_SetItem(self->dict, key, value);
436 Py_DECREF(key);
437 Py_DECREF(value);
438 if (err < 0)
439 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000440
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000441 self->ufd_uptodate = 0;
442
443 Py_INCREF(Py_None);
444 return Py_None;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000445}
446
447
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000448PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000449"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000450Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000451
452static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000453poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000454{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000455 PyObject *key;
456 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000457
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000458 fd = PyObject_AsFileDescriptor( o );
459 if (fd == -1)
460 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000462 /* Check whether the fd is already in the array */
463 key = PyInt_FromLong(fd);
464 if (key == NULL)
465 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000466
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000467 if (PyDict_DelItem(self->dict, key) == -1) {
468 Py_DECREF(key);
469 /* This will simply raise the KeyError set by PyDict_DelItem
470 if the file descriptor isn't registered. */
471 return NULL;
472 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000474 Py_DECREF(key);
475 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000476
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000477 Py_INCREF(Py_None);
478 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000479}
480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000481PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000482"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
483Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000484any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000485
486static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000487poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000489 PyObject *result_list = NULL, *tout = NULL;
490 int timeout = 0, poll_result, i, j;
491 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000493 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
494 return NULL;
495 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000497 /* Check values for timeout */
498 if (tout == NULL || tout == Py_None)
499 timeout = -1;
500 else if (!PyNumber_Check(tout)) {
501 PyErr_SetString(PyExc_TypeError,
502 "timeout must be an integer or None");
503 return NULL;
504 }
505 else {
506 tout = PyNumber_Int(tout);
507 if (!tout)
508 return NULL;
509 timeout = PyInt_AsLong(tout);
510 Py_DECREF(tout);
511 if (timeout == -1 && PyErr_Occurred())
512 return NULL;
513 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000514
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000515 /* Ensure the ufd array is up to date */
516 if (!self->ufd_uptodate)
517 if (update_ufd_array(self) == 0)
518 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000519
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000520 /* call poll() */
521 Py_BEGIN_ALLOW_THREADS
522 poll_result = poll(self->ufds, self->ufd_len, timeout);
523 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000524
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000525 if (poll_result < 0) {
526 PyErr_SetFromErrno(SelectError);
527 return NULL;
528 }
529
530 /* build the result list */
531
532 result_list = PyList_New(poll_result);
533 if (!result_list)
534 return NULL;
535 else {
536 for (i = 0, j = 0; j < poll_result; j++) {
537 /* skip to the next fired descriptor */
538 while (!self->ufds[i].revents) {
539 i++;
540 }
541 /* if we hit a NULL return, set value to NULL
542 and break out of loop; code at end will
543 clean up result_list */
544 value = PyTuple_New(2);
545 if (value == NULL)
546 goto error;
547 num = PyInt_FromLong(self->ufds[i].fd);
548 if (num == NULL) {
549 Py_DECREF(value);
550 goto error;
551 }
552 PyTuple_SET_ITEM(value, 0, num);
553
554 /* The &0xffff is a workaround for AIX. 'revents'
555 is a 16-bit short, and IBM assigned POLLNVAL
556 to be 0x8000, so the conversion to int results
557 in a negative number. See SF bug #923315. */
558 num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
559 if (num == NULL) {
560 Py_DECREF(value);
561 goto error;
562 }
563 PyTuple_SET_ITEM(value, 1, num);
564 if ((PyList_SetItem(result_list, j, value)) == -1) {
565 Py_DECREF(value);
566 goto error;
567 }
568 i++;
569 }
570 }
571 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000572
573 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000574 Py_DECREF(result_list);
575 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000576}
577
578static PyMethodDef poll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000579 {"register", (PyCFunction)poll_register,
580 METH_VARARGS, poll_register_doc},
581 {"modify", (PyCFunction)poll_modify,
582 METH_VARARGS, poll_modify_doc},
583 {"unregister", (PyCFunction)poll_unregister,
584 METH_O, poll_unregister_doc},
585 {"poll", (PyCFunction)poll_poll,
586 METH_VARARGS, poll_poll_doc},
587 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000588};
589
590static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000591newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000592{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000593 pollObject *self;
594 self = PyObject_New(pollObject, &poll_Type);
595 if (self == NULL)
596 return NULL;
597 /* ufd_uptodate is a Boolean, denoting whether the
598 array pointed to by ufds matches the contents of the dictionary. */
599 self->ufd_uptodate = 0;
600 self->ufds = NULL;
601 self->dict = PyDict_New();
602 if (self->dict == NULL) {
603 Py_DECREF(self);
604 return NULL;
605 }
606 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000607}
608
609static void
610poll_dealloc(pollObject *self)
611{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000612 if (self->ufds != NULL)
613 PyMem_DEL(self->ufds);
614 Py_XDECREF(self->dict);
615 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000616}
617
618static PyObject *
619poll_getattr(pollObject *self, char *name)
620{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000621 return Py_FindMethod(poll_methods, (PyObject *)self, name);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000622}
623
Tim Peters0c322792002-07-17 16:49:03 +0000624static PyTypeObject poll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000625 /* The ob_type field must be initialized in the module init function
626 * to be portable to Windows without using C++. */
627 PyVarObject_HEAD_INIT(NULL, 0)
628 "select.poll", /*tp_name*/
629 sizeof(pollObject), /*tp_basicsize*/
630 0, /*tp_itemsize*/
631 /* methods */
632 (destructor)poll_dealloc, /*tp_dealloc*/
633 0, /*tp_print*/
634 (getattrfunc)poll_getattr, /*tp_getattr*/
635 0, /*tp_setattr*/
636 0, /*tp_compare*/
637 0, /*tp_repr*/
638 0, /*tp_as_number*/
639 0, /*tp_as_sequence*/
640 0, /*tp_as_mapping*/
641 0, /*tp_hash*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000642};
643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000644PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000645"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000646unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000647
648static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +0000649select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000650{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000651 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000652}
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000653
654#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000655/*
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000656 * On some systems poll() sets errno on invalid file descriptors. We test
657 * for this at runtime because this bug may be fixed or introduced between
658 * OS releases.
659 */
660static int select_have_broken_poll(void)
661{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000662 int poll_test;
663 int filedes[2];
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000664
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000665 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000666
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000667 /* Create a file descriptor to make invalid */
668 if (pipe(filedes) < 0) {
669 return 1;
670 }
671 poll_struct.fd = filedes[0];
672 close(filedes[0]);
673 close(filedes[1]);
674 poll_test = poll(&poll_struct, 1, 0);
675 if (poll_test < 0) {
676 return 1;
677 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
678 return 1;
679 }
680 return 0;
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000681}
682#endif /* __APPLE__ */
683
684#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000685
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000686#ifdef HAVE_EPOLL
687/* **************************************************************************
688 * epoll interface for Linux 2.6
689 *
690 * Written by Christian Heimes
691 * Inspired by Twisted's _epoll.pyx and select.poll()
692 */
693
694#ifdef HAVE_SYS_EPOLL_H
695#include <sys/epoll.h>
696#endif
697
698typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000699 PyObject_HEAD
700 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000701} pyEpoll_Object;
702
703static PyTypeObject pyEpoll_Type;
704#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
705
706static PyObject *
707pyepoll_err_closed(void)
708{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000709 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
710 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000711}
712
713static int
714pyepoll_internal_close(pyEpoll_Object *self)
715{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000716 int save_errno = 0;
717 if (self->epfd >= 0) {
718 int epfd = self->epfd;
719 self->epfd = -1;
720 Py_BEGIN_ALLOW_THREADS
721 if (close(epfd) < 0)
722 save_errno = errno;
723 Py_END_ALLOW_THREADS
724 }
725 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000726}
727
728static PyObject *
729newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
730{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000731 pyEpoll_Object *self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000732
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000733 if (sizehint == -1) {
734 sizehint = FD_SETSIZE-1;
735 }
736 else if (sizehint < 1) {
737 PyErr_Format(PyExc_ValueError,
738 "sizehint must be greater zero, got %d",
739 sizehint);
740 return NULL;
741 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000742
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000743 assert(type != NULL && type->tp_alloc != NULL);
744 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
745 if (self == NULL)
746 return NULL;
747
748 if (fd == -1) {
749 Py_BEGIN_ALLOW_THREADS
750 self->epfd = epoll_create(sizehint);
751 Py_END_ALLOW_THREADS
752 }
753 else {
754 self->epfd = fd;
755 }
756 if (self->epfd < 0) {
757 Py_DECREF(self);
758 PyErr_SetFromErrno(PyExc_IOError);
759 return NULL;
760 }
761 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000762}
763
764
765static PyObject *
766pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
767{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000768 int sizehint = -1;
769 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000770
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000771 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
772 &sizehint))
773 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000774
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000775 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000776}
777
778
779static void
780pyepoll_dealloc(pyEpoll_Object *self)
781{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 (void)pyepoll_internal_close(self);
783 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000784}
785
786static PyObject*
787pyepoll_close(pyEpoll_Object *self)
788{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000789 errno = pyepoll_internal_close(self);
790 if (errno < 0) {
791 PyErr_SetFromErrno(PyExc_IOError);
792 return NULL;
793 }
794 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000795}
796
797PyDoc_STRVAR(pyepoll_close_doc,
798"close() -> None\n\
799\n\
800Close the epoll control file descriptor. Further operations on the epoll\n\
801object will raise an exception.");
802
803static PyObject*
804pyepoll_get_closed(pyEpoll_Object *self)
805{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000806 if (self->epfd < 0)
807 Py_RETURN_TRUE;
808 else
809 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000810}
811
812static PyObject*
813pyepoll_fileno(pyEpoll_Object *self)
814{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000815 if (self->epfd < 0)
816 return pyepoll_err_closed();
817 return PyInt_FromLong(self->epfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000818}
819
820PyDoc_STRVAR(pyepoll_fileno_doc,
821"fileno() -> int\n\
822\n\
823Return the epoll control file descriptor.");
824
825static PyObject*
826pyepoll_fromfd(PyObject *cls, PyObject *args)
827{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000828 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000829
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000830 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
831 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000832
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000833 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000834}
835
836PyDoc_STRVAR(pyepoll_fromfd_doc,
837"fromfd(fd) -> epoll\n\
838\n\
839Create an epoll object from a given control fd.");
840
841static PyObject *
842pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
843{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000844 struct epoll_event ev;
845 int result;
846 int fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000847
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 if (epfd < 0)
849 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000850
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000851 fd = PyObject_AsFileDescriptor(pfd);
852 if (fd == -1) {
853 return NULL;
854 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000855
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000856 switch(op) {
857 case EPOLL_CTL_ADD:
858 case EPOLL_CTL_MOD:
859 ev.events = events;
860 ev.data.fd = fd;
861 Py_BEGIN_ALLOW_THREADS
862 result = epoll_ctl(epfd, op, fd, &ev);
863 Py_END_ALLOW_THREADS
864 break;
865 case EPOLL_CTL_DEL:
866 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
867 * operation required a non-NULL pointer in event, even
868 * though this argument is ignored. */
869 Py_BEGIN_ALLOW_THREADS
870 result = epoll_ctl(epfd, op, fd, &ev);
871 if (errno == EBADF) {
872 /* fd already closed */
873 result = 0;
874 errno = 0;
875 }
876 Py_END_ALLOW_THREADS
877 break;
878 default:
879 result = -1;
880 errno = EINVAL;
881 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000882
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000883 if (result < 0) {
884 PyErr_SetFromErrno(PyExc_IOError);
885 return NULL;
886 }
887 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000888}
889
890static PyObject *
891pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
892{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000893 PyObject *pfd;
894 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
895 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000896
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000897 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
898 &pfd, &events)) {
899 return NULL;
900 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000901
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000902 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000903}
904
905PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl7d4bfb32010-08-02 21:44:25 +0000906"register(fd[, eventmask]) -> None\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000907\n\
Senthil Kumaran2bd91002011-06-26 23:50:35 -0700908Registers a new fd or raises an IOError if the fd is already registered.\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000909fd is the target file descriptor of the operation.\n\
910events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000911is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
912\n\
913The epoll interface supports all file descriptors that support poll.");
914
915static PyObject *
916pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
917{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000918 PyObject *pfd;
919 unsigned int events;
920 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000921
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000922 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
923 &pfd, &events)) {
924 return NULL;
925 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000926
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000927 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000928}
929
930PyDoc_STRVAR(pyepoll_modify_doc,
931"modify(fd, eventmask) -> None\n\
932\n\
933fd is the target file descriptor of the operation\n\
934events is a bit set composed of the various EPOLL constants");
935
936static PyObject *
937pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
938{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000939 PyObject *pfd;
940 static char *kwlist[] = {"fd", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000941
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000942 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
943 &pfd)) {
944 return NULL;
945 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000946
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000947 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000948}
949
950PyDoc_STRVAR(pyepoll_unregister_doc,
951"unregister(fd) -> None\n\
952\n\
953fd is the target file descriptor of the operation.");
954
955static PyObject *
956pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
957{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000958 double dtimeout = -1.;
959 int timeout;
960 int maxevents = -1;
961 int nfds, i;
962 PyObject *elist = NULL, *etuple = NULL;
963 struct epoll_event *evs = NULL;
964 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000965
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000966 if (self->epfd < 0)
967 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000968
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000969 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
970 &dtimeout, &maxevents)) {
971 return NULL;
972 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000973
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000974 if (dtimeout < 0) {
975 timeout = -1;
976 }
977 else if (dtimeout * 1000.0 > INT_MAX) {
978 PyErr_SetString(PyExc_OverflowError,
979 "timeout is too large");
980 return NULL;
981 }
982 else {
983 timeout = (int)(dtimeout * 1000.0);
984 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000985
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000986 if (maxevents == -1) {
987 maxevents = FD_SETSIZE-1;
988 }
989 else if (maxevents < 1) {
990 PyErr_Format(PyExc_ValueError,
991 "maxevents must be greater than 0, got %d",
992 maxevents);
993 return NULL;
994 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000995
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000996 evs = PyMem_New(struct epoll_event, maxevents);
997 if (evs == NULL) {
998 Py_DECREF(self);
999 PyErr_NoMemory();
1000 return NULL;
1001 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001002
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001003 Py_BEGIN_ALLOW_THREADS
1004 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1005 Py_END_ALLOW_THREADS
1006 if (nfds < 0) {
1007 PyErr_SetFromErrno(PyExc_IOError);
1008 goto error;
1009 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001010
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001011 elist = PyList_New(nfds);
1012 if (elist == NULL) {
1013 goto error;
1014 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001015
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001016 for (i = 0; i < nfds; i++) {
1017 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1018 if (etuple == NULL) {
1019 Py_CLEAR(elist);
1020 goto error;
1021 }
1022 PyList_SET_ITEM(elist, i, etuple);
1023 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001024
Georg Brandl018a3622008-03-26 12:57:47 +00001025 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001026 PyMem_Free(evs);
1027 return elist;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001028}
1029
1030PyDoc_STRVAR(pyepoll_poll_doc,
1031"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1032\n\
1033Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1034in seconds (as float). -1 makes poll wait indefinitely.\n\
1035Up to maxevents are returned to the caller.");
1036
1037static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001038 {"fromfd", (PyCFunction)pyepoll_fromfd,
1039 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1040 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1041 pyepoll_close_doc},
1042 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1043 pyepoll_fileno_doc},
1044 {"modify", (PyCFunction)pyepoll_modify,
1045 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1046 {"register", (PyCFunction)pyepoll_register,
1047 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1048 {"unregister", (PyCFunction)pyepoll_unregister,
1049 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1050 {"poll", (PyCFunction)pyepoll_poll,
1051 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1052 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001053};
1054
1055static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001056 {"closed", (getter)pyepoll_get_closed, NULL,
1057 "True if the epoll handler is closed"},
1058 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001059};
1060
1061PyDoc_STRVAR(pyepoll_doc,
1062"select.epoll([sizehint=-1])\n\
1063\n\
1064Returns an epolling object\n\
1065\n\
1066sizehint must be a positive integer or -1 for the default size. The\n\
1067sizehint is used to optimize internal data structures. It doesn't limit\n\
1068the maximum number of monitored events.");
1069
1070static PyTypeObject pyEpoll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001071 PyVarObject_HEAD_INIT(NULL, 0)
1072 "select.epoll", /* tp_name */
1073 sizeof(pyEpoll_Object), /* tp_basicsize */
1074 0, /* tp_itemsize */
1075 (destructor)pyepoll_dealloc, /* tp_dealloc */
1076 0, /* tp_print */
1077 0, /* tp_getattr */
1078 0, /* tp_setattr */
1079 0, /* tp_compare */
1080 0, /* tp_repr */
1081 0, /* tp_as_number */
1082 0, /* tp_as_sequence */
1083 0, /* tp_as_mapping */
1084 0, /* tp_hash */
1085 0, /* tp_call */
1086 0, /* tp_str */
1087 PyObject_GenericGetAttr, /* tp_getattro */
1088 0, /* tp_setattro */
1089 0, /* tp_as_buffer */
1090 Py_TPFLAGS_DEFAULT, /* tp_flags */
1091 pyepoll_doc, /* tp_doc */
1092 0, /* tp_traverse */
1093 0, /* tp_clear */
1094 0, /* tp_richcompare */
1095 0, /* tp_weaklistoffset */
1096 0, /* tp_iter */
1097 0, /* tp_iternext */
1098 pyepoll_methods, /* tp_methods */
1099 0, /* tp_members */
1100 pyepoll_getsetlist, /* tp_getset */
1101 0, /* tp_base */
1102 0, /* tp_dict */
1103 0, /* tp_descr_get */
1104 0, /* tp_descr_set */
1105 0, /* tp_dictoffset */
1106 0, /* tp_init */
1107 0, /* tp_alloc */
1108 pyepoll_new, /* tp_new */
1109 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001110};
1111
1112#endif /* HAVE_EPOLL */
1113
1114#ifdef HAVE_KQUEUE
1115/* **************************************************************************
1116 * kqueue interface for BSD
1117 *
1118 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1119 * All rights reserved.
1120 *
1121 * Redistribution and use in source and binary forms, with or without
1122 * modification, are permitted provided that the following conditions
1123 * are met:
1124 * 1. Redistributions of source code must retain the above copyright
1125 * notice, this list of conditions and the following disclaimer.
1126 * 2. Redistributions in binary form must reproduce the above copyright
1127 * notice, this list of conditions and the following disclaimer in the
1128 * documentation and/or other materials provided with the distribution.
1129 *
1130 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1131 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1132 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1133 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1134 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1135 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1136 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1137 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1138 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1139 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1140 * SUCH DAMAGE.
1141 */
1142
1143#ifdef HAVE_SYS_EVENT_H
1144#include <sys/event.h>
1145#endif
1146
1147PyDoc_STRVAR(kqueue_event_doc,
Georg Brandlfa1ffb62009-12-29 21:09:17 +00001148"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001149\n\
1150This object is the equivalent of the struct kevent for the C API.\n\
1151\n\
1152See the kqueue manpage for more detailed information about the meaning\n\
1153of the arguments.\n\
1154\n\
1155One minor note: while you might hope that udata could store a\n\
1156reference to a python object, it cannot, because it is impossible to\n\
1157keep a proper reference count of the object once it's passed into the\n\
1158kernel. Therefore, I have restricted it to only storing an integer. I\n\
1159recommend ignoring it and simply using the 'ident' field to key off\n\
1160of. You could also set up a dictionary on the python side to store a\n\
1161udata->object mapping.");
1162
1163typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001164 PyObject_HEAD
1165 struct kevent e;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001166} kqueue_event_Object;
1167
1168static PyTypeObject kqueue_event_Type;
1169
1170#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1171
1172typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001173 PyObject_HEAD
1174 SOCKET kqfd; /* kqueue control fd */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001175} kqueue_queue_Object;
1176
1177static PyTypeObject kqueue_queue_Type;
1178
1179#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1180
Antoine Pitrou323b9da2009-11-04 19:25:14 +00001181#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1182# error uintptr_t does not match void *!
1183#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1184# define T_UINTPTRT T_ULONGLONG
1185# define T_INTPTRT T_LONGLONG
1186# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1187# define UINTPTRT_FMT_UNIT "K"
1188# define INTPTRT_FMT_UNIT "L"
1189#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1190# define T_UINTPTRT T_ULONG
1191# define T_INTPTRT T_LONG
1192# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1193# define UINTPTRT_FMT_UNIT "k"
1194# define INTPTRT_FMT_UNIT "l"
1195#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1196# define T_UINTPTRT T_UINT
1197# define T_INTPTRT T_INT
1198# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1199# define UINTPTRT_FMT_UNIT "I"
1200# define INTPTRT_FMT_UNIT "i"
1201#else
1202# error uintptr_t does not match int, long, or long long!
1203#endif
1204
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001205/* Unfortunately, we can't store python objects in udata, because
1206 * kevents in the kernel can be removed without warning, which would
1207 * forever lose the refcount on the object stored with it.
1208 */
1209
1210#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1211static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001212 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1213 {"filter", T_SHORT, KQ_OFF(e.filter)},
1214 {"flags", T_USHORT, KQ_OFF(e.flags)},
1215 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1216 {"data", T_INTPTRT, KQ_OFF(e.data)},
1217 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1218 {NULL} /* Sentinel */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001219};
1220#undef KQ_OFF
1221
1222static PyObject *
Georg Brandlea370a92010-02-23 21:48:57 +00001223
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001224kqueue_event_repr(kqueue_event_Object *s)
1225{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001226 char buf[1024];
1227 PyOS_snprintf(
1228 buf, sizeof(buf),
1229 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1230 "data=0x%zd udata=%p>",
1231 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1232 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1233 return PyString_FromString(buf);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001234}
1235
1236static int
1237kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1238{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001239 PyObject *pfd;
1240 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1241 "data", "udata", NULL};
1242 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001243
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001244 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001245
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001246 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1247 &pfd, &(self->e.filter), &(self->e.flags),
1248 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1249 return -1;
1250 }
1251
1252 if (PyLong_Check(pfd)) {
1253 self->e.ident = PyLong_AsUintptr_t(pfd);
1254 }
1255 else {
1256 self->e.ident = PyObject_AsFileDescriptor(pfd);
1257 }
1258 if (PyErr_Occurred()) {
1259 return -1;
1260 }
1261 return 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001262}
1263
1264static PyObject *
1265kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001266 int op)
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001267{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001268 Py_intptr_t result = 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001269
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001270 if (!kqueue_event_Check(o)) {
1271 if (op == Py_EQ || op == Py_NE) {
1272 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1273 Py_INCREF(res);
1274 return res;
1275 }
1276 PyErr_Format(PyExc_TypeError,
1277 "can't compare %.200s to %.200s",
1278 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1279 return NULL;
1280 }
1281 if (((result = s->e.ident - o->e.ident) == 0) &&
1282 ((result = s->e.filter - o->e.filter) == 0) &&
1283 ((result = s->e.flags - o->e.flags) == 0) &&
1284 ((result = s->e.fflags - o->e.fflags) == 0) &&
1285 ((result = s->e.data - o->e.data) == 0) &&
1286 ((result = s->e.udata - o->e.udata) == 0)
1287 ) {
1288 result = 0;
1289 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001290
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001291 switch (op) {
1292 case Py_EQ:
1293 result = (result == 0);
1294 break;
1295 case Py_NE:
1296 result = (result != 0);
1297 break;
1298 case Py_LE:
1299 result = (result <= 0);
1300 break;
1301 case Py_GE:
1302 result = (result >= 0);
1303 break;
1304 case Py_LT:
1305 result = (result < 0);
1306 break;
1307 case Py_GT:
1308 result = (result > 0);
1309 break;
1310 }
1311 return PyBool_FromLong((long)result);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001312}
1313
1314static PyTypeObject kqueue_event_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001315 PyVarObject_HEAD_INIT(NULL, 0)
1316 "select.kevent", /* tp_name */
1317 sizeof(kqueue_event_Object), /* tp_basicsize */
1318 0, /* tp_itemsize */
1319 0, /* tp_dealloc */
1320 0, /* tp_print */
1321 0, /* tp_getattr */
1322 0, /* tp_setattr */
1323 0, /* tp_compare */
1324 (reprfunc)kqueue_event_repr, /* tp_repr */
1325 0, /* tp_as_number */
1326 0, /* tp_as_sequence */
1327 0, /* tp_as_mapping */
1328 0, /* tp_hash */
1329 0, /* tp_call */
1330 0, /* tp_str */
1331 0, /* tp_getattro */
1332 0, /* tp_setattro */
1333 0, /* tp_as_buffer */
1334 Py_TPFLAGS_DEFAULT, /* tp_flags */
1335 kqueue_event_doc, /* tp_doc */
1336 0, /* tp_traverse */
1337 0, /* tp_clear */
1338 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1339 0, /* tp_weaklistoffset */
1340 0, /* tp_iter */
1341 0, /* tp_iternext */
1342 0, /* tp_methods */
1343 kqueue_event_members, /* tp_members */
1344 0, /* tp_getset */
1345 0, /* tp_base */
1346 0, /* tp_dict */
1347 0, /* tp_descr_get */
1348 0, /* tp_descr_set */
1349 0, /* tp_dictoffset */
1350 (initproc)kqueue_event_init, /* tp_init */
1351 0, /* tp_alloc */
1352 0, /* tp_new */
1353 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001354};
1355
1356static PyObject *
1357kqueue_queue_err_closed(void)
1358{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001359 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1360 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001361}
1362
1363static int
1364kqueue_queue_internal_close(kqueue_queue_Object *self)
1365{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001366 int save_errno = 0;
1367 if (self->kqfd >= 0) {
1368 int kqfd = self->kqfd;
1369 self->kqfd = -1;
1370 Py_BEGIN_ALLOW_THREADS
1371 if (close(kqfd) < 0)
1372 save_errno = errno;
1373 Py_END_ALLOW_THREADS
1374 }
1375 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001376}
1377
1378static PyObject *
1379newKqueue_Object(PyTypeObject *type, SOCKET fd)
1380{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001381 kqueue_queue_Object *self;
1382 assert(type != NULL && type->tp_alloc != NULL);
1383 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1384 if (self == NULL) {
1385 return NULL;
1386 }
1387
1388 if (fd == -1) {
1389 Py_BEGIN_ALLOW_THREADS
1390 self->kqfd = kqueue();
1391 Py_END_ALLOW_THREADS
1392 }
1393 else {
1394 self->kqfd = fd;
1395 }
1396 if (self->kqfd < 0) {
1397 Py_DECREF(self);
1398 PyErr_SetFromErrno(PyExc_IOError);
1399 return NULL;
1400 }
1401 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001402}
1403
1404static PyObject *
1405kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1406{
1407
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001408 if ((args != NULL && PyObject_Size(args)) ||
1409 (kwds != NULL && PyObject_Size(kwds))) {
1410 PyErr_SetString(PyExc_ValueError,
1411 "select.kqueue doesn't accept arguments");
1412 return NULL;
1413 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001414
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001415 return newKqueue_Object(type, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001416}
1417
1418static void
1419kqueue_queue_dealloc(kqueue_queue_Object *self)
1420{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001421 kqueue_queue_internal_close(self);
1422 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001423}
1424
1425static PyObject*
1426kqueue_queue_close(kqueue_queue_Object *self)
1427{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001428 errno = kqueue_queue_internal_close(self);
1429 if (errno < 0) {
1430 PyErr_SetFromErrno(PyExc_IOError);
1431 return NULL;
1432 }
1433 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001434}
1435
1436PyDoc_STRVAR(kqueue_queue_close_doc,
1437"close() -> None\n\
1438\n\
1439Close the kqueue control file descriptor. Further operations on the kqueue\n\
1440object will raise an exception.");
1441
1442static PyObject*
1443kqueue_queue_get_closed(kqueue_queue_Object *self)
1444{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001445 if (self->kqfd < 0)
1446 Py_RETURN_TRUE;
1447 else
1448 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001449}
1450
1451static PyObject*
1452kqueue_queue_fileno(kqueue_queue_Object *self)
1453{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001454 if (self->kqfd < 0)
1455 return kqueue_queue_err_closed();
1456 return PyInt_FromLong(self->kqfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001457}
1458
1459PyDoc_STRVAR(kqueue_queue_fileno_doc,
1460"fileno() -> int\n\
1461\n\
1462Return the kqueue control file descriptor.");
1463
1464static PyObject*
1465kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1466{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001467 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001468
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001469 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1470 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001471
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001472 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001473}
1474
1475PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1476"fromfd(fd) -> kqueue\n\
1477\n\
1478Create a kqueue object from a given control fd.");
1479
1480static PyObject *
1481kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1482{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001483 int nevents = 0;
1484 int gotevents = 0;
1485 int nchanges = 0;
1486 int i = 0;
1487 PyObject *otimeout = NULL;
1488 PyObject *ch = NULL;
1489 PyObject *it = NULL, *ei = NULL;
1490 PyObject *result = NULL;
1491 struct kevent *evl = NULL;
1492 struct kevent *chl = NULL;
1493 struct timespec timeoutspec;
1494 struct timespec *ptimeoutspec;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001495
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001496 if (self->kqfd < 0)
1497 return kqueue_queue_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001498
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001499 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1500 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001501
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001502 if (nevents < 0) {
1503 PyErr_Format(PyExc_ValueError,
1504 "Length of eventlist must be 0 or positive, got %d",
1505 nevents);
1506 return NULL;
1507 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001508
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001509 if (otimeout == Py_None || otimeout == NULL) {
1510 ptimeoutspec = NULL;
1511 }
1512 else if (PyNumber_Check(otimeout)) {
1513 double timeout;
1514 long seconds;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001515
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001516 timeout = PyFloat_AsDouble(otimeout);
1517 if (timeout == -1 && PyErr_Occurred())
1518 return NULL;
1519 if (timeout > (double)LONG_MAX) {
1520 PyErr_SetString(PyExc_OverflowError,
1521 "timeout period too long");
1522 return NULL;
1523 }
1524 if (timeout < 0) {
1525 PyErr_SetString(PyExc_ValueError,
1526 "timeout must be positive or None");
1527 return NULL;
1528 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001529
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001530 seconds = (long)timeout;
1531 timeout = timeout - (double)seconds;
1532 timeoutspec.tv_sec = seconds;
1533 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1534 ptimeoutspec = &timeoutspec;
1535 }
1536 else {
1537 PyErr_Format(PyExc_TypeError,
1538 "timeout argument must be an number "
1539 "or None, got %.200s",
1540 Py_TYPE(otimeout)->tp_name);
1541 return NULL;
1542 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001543
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001544 if (ch != NULL && ch != Py_None) {
1545 it = PyObject_GetIter(ch);
1546 if (it == NULL) {
1547 PyErr_SetString(PyExc_TypeError,
1548 "changelist is not iterable");
1549 return NULL;
1550 }
1551 nchanges = PyObject_Size(ch);
1552 if (nchanges < 0) {
1553 goto error;
1554 }
Georg Brandlea370a92010-02-23 21:48:57 +00001555
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001556 chl = PyMem_New(struct kevent, nchanges);
1557 if (chl == NULL) {
1558 PyErr_NoMemory();
1559 goto error;
1560 }
1561 i = 0;
1562 while ((ei = PyIter_Next(it)) != NULL) {
1563 if (!kqueue_event_Check(ei)) {
1564 Py_DECREF(ei);
1565 PyErr_SetString(PyExc_TypeError,
1566 "changelist must be an iterable of "
1567 "select.kevent objects");
1568 goto error;
1569 } else {
1570 chl[i++] = ((kqueue_event_Object *)ei)->e;
1571 }
1572 Py_DECREF(ei);
1573 }
1574 }
1575 Py_CLEAR(it);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001576
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001577 /* event list */
1578 if (nevents) {
1579 evl = PyMem_New(struct kevent, nevents);
1580 if (evl == NULL) {
1581 PyErr_NoMemory();
1582 goto error;
1583 }
1584 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001585
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001586 Py_BEGIN_ALLOW_THREADS
1587 gotevents = kevent(self->kqfd, chl, nchanges,
1588 evl, nevents, ptimeoutspec);
1589 Py_END_ALLOW_THREADS
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001590
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001591 if (gotevents == -1) {
1592 PyErr_SetFromErrno(PyExc_OSError);
1593 goto error;
1594 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001595
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001596 result = PyList_New(gotevents);
1597 if (result == NULL) {
1598 goto error;
1599 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001600
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001601 for (i = 0; i < gotevents; i++) {
1602 kqueue_event_Object *ch;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001603
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001604 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1605 if (ch == NULL) {
1606 goto error;
1607 }
1608 ch->e = evl[i];
1609 PyList_SET_ITEM(result, i, (PyObject *)ch);
1610 }
1611 PyMem_Free(chl);
1612 PyMem_Free(evl);
1613 return result;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001614
1615 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001616 PyMem_Free(chl);
1617 PyMem_Free(evl);
1618 Py_XDECREF(result);
1619 Py_XDECREF(it);
1620 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001621}
1622
1623PyDoc_STRVAR(kqueue_queue_control_doc,
Georg Brandl2f3bd832008-09-21 07:14:44 +00001624"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001625\n\
1626Calls the kernel kevent function.\n\
1627- changelist must be a list of kevent objects describing the changes\n\
1628 to be made to the kernel's watch list or None.\n\
1629- max_events lets you specify the maximum number of events that the\n\
1630 kernel will return.\n\
1631- timeout is the maximum time to wait in seconds, or else None,\n\
1632 to wait forever. timeout accepts floats for smaller timeouts, too.");
1633
1634
1635static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001636 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1637 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1638 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1639 kqueue_queue_close_doc},
1640 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1641 kqueue_queue_fileno_doc},
1642 {"control", (PyCFunction)kqueue_queue_control,
1643 METH_VARARGS , kqueue_queue_control_doc},
1644 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001645};
1646
1647static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001648 {"closed", (getter)kqueue_queue_get_closed, NULL,
1649 "True if the kqueue handler is closed"},
1650 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001651};
1652
1653PyDoc_STRVAR(kqueue_queue_doc,
1654"Kqueue syscall wrapper.\n\
1655\n\
1656For example, to start watching a socket for input:\n\
1657>>> kq = kqueue()\n\
1658>>> sock = socket()\n\
1659>>> sock.connect((host, port))\n\
1660>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1661\n\
1662To wait one second for it to become writeable:\n\
1663>>> kq.control(None, 1, 1000)\n\
1664\n\
1665To stop listening:\n\
1666>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1667
1668static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001669 PyVarObject_HEAD_INIT(NULL, 0)
1670 "select.kqueue", /* tp_name */
1671 sizeof(kqueue_queue_Object), /* tp_basicsize */
1672 0, /* tp_itemsize */
1673 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1674 0, /* tp_print */
1675 0, /* tp_getattr */
1676 0, /* tp_setattr */
1677 0, /* tp_compare */
1678 0, /* tp_repr */
1679 0, /* tp_as_number */
1680 0, /* tp_as_sequence */
1681 0, /* tp_as_mapping */
1682 0, /* tp_hash */
1683 0, /* tp_call */
1684 0, /* tp_str */
1685 0, /* tp_getattro */
1686 0, /* tp_setattro */
1687 0, /* tp_as_buffer */
1688 Py_TPFLAGS_DEFAULT, /* tp_flags */
1689 kqueue_queue_doc, /* tp_doc */
1690 0, /* tp_traverse */
1691 0, /* tp_clear */
1692 0, /* tp_richcompare */
1693 0, /* tp_weaklistoffset */
1694 0, /* tp_iter */
1695 0, /* tp_iternext */
1696 kqueue_queue_methods, /* tp_methods */
1697 0, /* tp_members */
1698 kqueue_queue_getsetlist, /* tp_getset */
1699 0, /* tp_base */
1700 0, /* tp_dict */
1701 0, /* tp_descr_get */
1702 0, /* tp_descr_set */
1703 0, /* tp_dictoffset */
1704 0, /* tp_init */
1705 0, /* tp_alloc */
1706 kqueue_queue_new, /* tp_new */
1707 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001708};
1709
1710#endif /* HAVE_KQUEUE */
1711/* ************************************************************************ */
1712
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001713PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001714"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1715\n\
1716Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001717The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001718rlist -- wait until ready for reading\n\
1719wlist -- wait until ready for writing\n\
1720xlist -- wait for an ``exceptional condition''\n\
1721If only one kind of condition is required, pass [] for the other lists.\n\
1722A file descriptor is either a socket or file object, or a small integer\n\
1723gotten from a fileno() method call on one of those.\n\
1724\n\
1725The optional 4th argument specifies a timeout in seconds; it may be\n\
1726a floating point number to specify fractions of seconds. If it is absent\n\
1727or None, the call will never time out.\n\
1728\n\
1729The return value is a tuple of three lists corresponding to the first three\n\
1730arguments; each contains the subset of the corresponding file descriptors\n\
1731that are ready.\n\
1732\n\
1733*** IMPORTANT NOTICE ***\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001734On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +00001735descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001736
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001737static PyMethodDef select_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001738 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001739#ifdef HAVE_POLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001740 {"poll", select_poll, METH_NOARGS, poll_doc},
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001741#endif /* HAVE_POLL */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001742 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001743};
1744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001746"This module supports asynchronous I/O on multiple file descriptors.\n\
1747\n\
1748*** IMPORTANT NOTICE ***\n\
Neal Norwitz2a30cd02006-07-10 01:18:57 +00001749On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001750
Mark Hammond62b1ab12002-07-23 06:31:15 +00001751PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001752initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001753{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001754 PyObject *m;
1755 m = Py_InitModule3("select", select_methods, module_doc);
1756 if (m == NULL)
1757 return;
Fred Drake4baedc12002-04-01 14:53:37 +00001758
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001759 SelectError = PyErr_NewException("select.error", NULL, NULL);
1760 Py_INCREF(SelectError);
1761 PyModule_AddObject(m, "error", SelectError);
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001762
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001763#ifdef PIPE_BUF
R. David Murray1d9d16e2010-10-16 00:43:13 +00001764#ifdef HAVE_BROKEN_PIPE_BUF
1765#undef PIPE_BUF
1766#define PIPE_BUF 512
1767#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001768 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001769#endif
Gregory P. Smith9d36fd22009-07-03 20:48:31 +00001770
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001771#if defined(HAVE_POLL)
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001772#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001773 if (select_have_broken_poll()) {
1774 if (PyObject_DelAttrString(m, "poll") == -1) {
1775 PyErr_Clear();
1776 }
1777 } else {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001778#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001779 {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001780#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001781 Py_TYPE(&poll_Type) = &PyType_Type;
1782 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1783 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1784 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1785 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1786 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1787 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001788
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001789#ifdef POLLRDNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001790 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001791#endif
1792#ifdef POLLRDBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001793 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001794#endif
1795#ifdef POLLWRNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001796 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001797#endif
1798#ifdef POLLWRBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001799 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001800#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001801#ifdef POLLMSG
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001802 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001803#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001804 }
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001805#endif /* HAVE_POLL */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001806
1807#ifdef HAVE_EPOLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001808 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1809 if (PyType_Ready(&pyEpoll_Type) < 0)
1810 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001811
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001812 Py_INCREF(&pyEpoll_Type);
1813 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001814
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001815 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1816 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1817 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1818 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1819 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1820 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001821#ifdef EPOLLONESHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001822 /* Kernel 2.6.2+ */
1823 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001824#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001825 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1826 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1827 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1828 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1829 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1830 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001831#endif /* HAVE_EPOLL */
1832
1833#ifdef HAVE_KQUEUE
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001834 kqueue_event_Type.tp_new = PyType_GenericNew;
1835 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1836 if(PyType_Ready(&kqueue_event_Type) < 0)
1837 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001838
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001839 Py_INCREF(&kqueue_event_Type);
1840 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001841
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001842 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1843 if(PyType_Ready(&kqueue_queue_Type) < 0)
1844 return;
1845 Py_INCREF(&kqueue_queue_Type);
1846 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1847
1848 /* event filters */
1849 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1850 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1851 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1852 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1853 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001854#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001855 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001856#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001857 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1858 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001859
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001860 /* event flags */
1861 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1862 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1863 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1864 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1865 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1866 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001867
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001868 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1869 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001870
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001871 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1872 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001873
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001874 /* READ WRITE filter flag */
1875 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001876
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001877 /* VNODE filter flags */
1878 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1879 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1880 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1881 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1882 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1883 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1884 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001885
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001886 /* PROC filter flags */
1887 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1888 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1889 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1890 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1891 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001892
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001893 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1894 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1895 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1896
1897 /* NETDEV filter flags */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001898#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001899 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1900 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001902#endif
1903
1904#endif /* HAVE_KQUEUE */
Guido van Rossumed233a51992-06-23 09:07:03 +00001905}