blob: 650d9fe3fba04a11ae23dad4ca2d271c9e386731 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Christian Heimes0e9ab5f2008-03-21 23:49:44 +000010#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000011
Ronald Oussoren32fd16e2006-04-23 12:36:23 +000012#ifdef __APPLE__
13 /* Perform runtime testing for a broken poll on OSX to make it easier
14 * to use the same binary on multiple releases of the OS.
15 */
16#undef HAVE_BROKEN_POLL
17#endif
18
Tim Petersd92dfe02000-12-12 01:18:41 +000019/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
20 64 is too small (too many people have bumped into that limit).
21 Here we boost it.
22 Users who want even more than the boosted limit should #define
23 FD_SETSIZE higher before this; e.g., via compiler /D switch.
24*/
25#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
26#define FD_SETSIZE 512
Antoine Pitrouc83ea132010-05-09 14:46:46 +000027#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000028
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000030#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000031#elif defined(HAVE_SYS_POLL_H)
32#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000033#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000034
Guido van Rossum37273171996-12-09 18:47:43 +000035#ifdef __sgi
36/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000037extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000038#endif
39
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000040#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000042#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000044#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#include <sys/time.h>
46#include <utils.h>
47#endif
48
Guido van Rossum6f489d91996-06-28 20:15:15 +000049#ifdef MS_WINDOWS
Kristján Valur Jónssonf6f3c4a2010-11-03 13:27:33 +000050# include <winsock2.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051#else
Neal Norwitz2a30cd02006-07-10 01:18:57 +000052# define SOCKET int
53# ifdef __BEOS__
54# include <net/socket.h>
55# elif defined(__VMS)
56# include <socket.h>
57# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000058#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000059
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000060static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000061
Barry Warsawc1cb3601996-12-12 22:16:21 +000062/* list of Python objects and their file descriptor */
63typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000064 PyObject *obj; /* owned reference */
65 SOCKET fd;
66 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000067} pylist;
68
Barry Warsawc1cb3601996-12-12 22:16:21 +000069static void
Tim Peters4b046c22001-08-16 21:59:46 +000070reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000071{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000072 int i;
73 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
74 Py_XDECREF(fd2obj[i].obj);
75 fd2obj[i].obj = NULL;
76 }
77 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000078}
79
80
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000081/* returns -1 and sets the Python exception if an error occurred, otherwise
82 returns a number >= 0
83*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000084static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000085seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000086{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000087 int i;
88 int max = -1;
89 int index = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000090 PyObject* fast_seq = NULL;
91 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000092
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
94 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000095
Antoine Pitrouc83ea132010-05-09 14:46:46 +000096 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
97 if (!fast_seq)
98 return -1;
99
Antoine Pitrou0552fc22012-11-01 20:13:54 +0100100 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000105 return -1;
106
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000107 Py_INCREF(o);
108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000112 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#else /* !_MSC_VER */
Charles-François Natalifda7b372011-08-28 16:22:33 +0200114 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
134 }
135 Py_DECREF(fast_seq);
136 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137
138 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000139 Py_XDECREF(o);
140 Py_DECREF(fast_seq);
141 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000142}
143
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144/* returns NULL and sets the Python exception if an error occurred */
145static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000146set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000147{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000148 int i, j, count=0;
149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000152 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
153 if (FD_ISSET(fd2obj[j].fd, set))
154 count++;
155 }
156 list = PyList_New(count);
157 if (!list)
158 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000164 o = fd2obj[j].obj;
165 fd2obj[j].obj = NULL;
166 /* transfer ownership */
167 if (PyList_SetItem(list, i, o) < 0)
168 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000169
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000170 i++;
171 }
172 }
173 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000175 Py_DECREF(list);
176 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000177}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000178
Barry Warsawb44740f2001-08-16 16:52:59 +0000179#undef SELECT_USES_HEAP
180#if FD_SETSIZE > 1024
181#define SELECT_USES_HEAP
182#endif /* FD_SETSIZE > 1024 */
183
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000184static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000185select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000186{
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000188 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000189#else /* !SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000190 /* XXX: All this should probably be implemented as follows:
191 * - find the highest descriptor we're interested in
192 * - add one
193 * - that's the size
194 * See: Stevens, APitUE, $12.5.1
195 */
196 pylist rfd2obj[FD_SETSIZE + 1];
197 pylist wfd2obj[FD_SETSIZE + 1];
198 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000199#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000200 PyObject *ifdlist, *ofdlist, *efdlist;
201 PyObject *ret = NULL;
202 PyObject *tout = Py_None;
203 fd_set ifdset, ofdset, efdset;
204 double timeout;
205 struct timeval tv, *tvp;
206 long seconds;
207 int imax, omax, emax, max;
208 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000209
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000210 /* convert arguments */
211 if (!PyArg_UnpackTuple(args, "select", 3, 4,
212 &ifdlist, &ofdlist, &efdlist, &tout))
213 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000214
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 if (tout == Py_None)
216 tvp = (struct timeval *)0;
217 else if (!PyNumber_Check(tout)) {
218 PyErr_SetString(PyExc_TypeError,
219 "timeout must be a float or None");
220 return NULL;
221 }
222 else {
223 timeout = PyFloat_AsDouble(tout);
224 if (timeout == -1 && PyErr_Occurred())
225 return NULL;
226 if (timeout > (double)LONG_MAX) {
227 PyErr_SetString(PyExc_OverflowError,
228 "timeout period too long");
229 return NULL;
230 }
231 seconds = (long)timeout;
232 timeout = timeout - (double)seconds;
233 tv.tv_sec = seconds;
234 tv.tv_usec = (long)(timeout * 1E6);
235 tvp = &tv;
236 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000237
Guido van Rossumed233a51992-06-23 09:07:03 +0000238
Barry Warsawb44740f2001-08-16 16:52:59 +0000239#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000240 /* Allocate memory for the lists */
241 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
242 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
243 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
244 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
245 if (rfd2obj) PyMem_DEL(rfd2obj);
246 if (wfd2obj) PyMem_DEL(wfd2obj);
247 if (efd2obj) PyMem_DEL(efd2obj);
248 return PyErr_NoMemory();
249 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000251 /* Convert sequences to fd_sets, and get maximum fd number
252 * propagates the Python exception set in seq2set()
253 */
254 rfd2obj[0].sentinel = -1;
255 wfd2obj[0].sentinel = -1;
256 efd2obj[0].sentinel = -1;
257 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
258 goto finally;
259 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
260 goto finally;
261 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
262 goto finally;
263 max = imax;
264 if (omax > max) max = omax;
265 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000266
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000267 Py_BEGIN_ALLOW_THREADS
268 n = select(max, &ifdset, &ofdset, &efdset, tvp);
269 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000270
Thomas Heller106f4c72002-09-24 16:51:00 +0000271#ifdef MS_WINDOWS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 if (n == SOCKET_ERROR) {
273 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
274 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000275#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 if (n < 0) {
277 PyErr_SetFromErrno(SelectError);
278 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000279#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000280 else {
281 /* any of these three calls can raise an exception. it's more
282 convenient to test for this after all three calls... but
283 is that acceptable?
284 */
285 ifdlist = set2list(&ifdset, rfd2obj);
286 ofdlist = set2list(&ofdset, wfd2obj);
287 efdlist = set2list(&efdset, efd2obj);
288 if (PyErr_Occurred())
289 ret = NULL;
290 else
291 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000292
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293 Py_DECREF(ifdlist);
294 Py_DECREF(ofdlist);
295 Py_DECREF(efdlist);
296 }
297
Barry Warsawc1cb3601996-12-12 22:16:21 +0000298 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299 reap_obj(rfd2obj);
300 reap_obj(wfd2obj);
301 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000302#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000303 PyMem_DEL(rfd2obj);
304 PyMem_DEL(wfd2obj);
305 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000306#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000307 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000308}
309
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000310#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000311/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000312 * poll() support
313 */
314
315typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000316 PyObject_HEAD
317 PyObject *dict;
318 int ufd_uptodate;
319 int ufd_len;
320 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000321} pollObject;
322
Jeremy Hylton938ace62002-07-17 16:30:39 +0000323static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000324
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000325/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000326 contained within a pollObject. Return 1 on success, 0 on an error.
327*/
328
329static int
330update_ufd_array(pollObject *self)
331{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000332 Py_ssize_t i, pos;
333 PyObject *key, *value;
334 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000336 self->ufd_len = PyDict_Size(self->dict);
337 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
338 if (self->ufds == NULL) {
339 self->ufds = old_ufds;
340 PyErr_NoMemory();
341 return 0;
342 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000343
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000344 i = pos = 0;
345 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200346 assert(i < self->ufd_len);
347 /* Never overflow */
348 self->ufds[i].fd = (int)PyInt_AsLong(key);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000349 self->ufds[i].events = (short)PyInt_AsLong(value);
350 i++;
351 }
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200352 assert(i == self->ufd_len);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000353 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;
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200368 int fd;
369 short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000370 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000371
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200372 if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000373 return NULL;
374 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000375
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000376 fd = PyObject_AsFileDescriptor(o);
377 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000378
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000379 /* Add entry to the internal dictionary: the key is the
380 file descriptor, and the value is the event mask. */
381 key = PyInt_FromLong(fd);
382 if (key == NULL)
383 return NULL;
384 value = PyInt_FromLong(events);
385 if (value == NULL) {
386 Py_DECREF(key);
387 return NULL;
388 }
389 err = PyDict_SetItem(self->dict, key, value);
390 Py_DECREF(key);
391 Py_DECREF(value);
392 if (err < 0)
393 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000394
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000395 self->ufd_uptodate = 0;
396
397 Py_INCREF(Py_None);
398 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000399}
400
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000401PyDoc_STRVAR(poll_modify_doc,
402"modify(fd, eventmask) -> None\n\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000403Modify an already registered file descriptor.\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000404fd -- either an integer, or an object with a fileno() method returning an\n\
405 int.\n\
406events -- an optional bitmask describing the type of events to check for");
407
408static PyObject *
409poll_modify(pollObject *self, PyObject *args)
410{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000411 PyObject *o, *key, *value;
412 int fd, events;
413 int err;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000414
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000415 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
416 return NULL;
417 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000418
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000419 fd = PyObject_AsFileDescriptor(o);
420 if (fd == -1) return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000421
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000422 /* Modify registered fd */
423 key = PyInt_FromLong(fd);
424 if (key == NULL)
425 return NULL;
426 if (PyDict_GetItem(self->dict, key) == NULL) {
427 errno = ENOENT;
428 PyErr_SetFromErrno(PyExc_IOError);
429 return NULL;
430 }
431 value = PyInt_FromLong(events);
432 if (value == NULL) {
433 Py_DECREF(key);
434 return NULL;
435 }
436 err = PyDict_SetItem(self->dict, key, value);
437 Py_DECREF(key);
438 Py_DECREF(value);
439 if (err < 0)
440 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000441
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000442 self->ufd_uptodate = 0;
443
444 Py_INCREF(Py_None);
445 return Py_None;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000446}
447
448
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000449PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000451Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452
453static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000456 PyObject *key;
457 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000459 fd = PyObject_AsFileDescriptor( o );
460 if (fd == -1)
461 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000463 /* Check whether the fd is already in the array */
464 key = PyInt_FromLong(fd);
465 if (key == NULL)
466 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000467
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000468 if (PyDict_DelItem(self->dict, key) == -1) {
469 Py_DECREF(key);
470 /* This will simply raise the KeyError set by PyDict_DelItem
471 if the file descriptor isn't registered. */
472 return NULL;
473 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000475 Py_DECREF(key);
476 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000477
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000478 Py_INCREF(Py_None);
479 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480}
481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000482PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
484Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486
487static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000488poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000490 PyObject *result_list = NULL, *tout = NULL;
491 int timeout = 0, poll_result, i, j;
492 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000494 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
495 return NULL;
496 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000497
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000498 /* Check values for timeout */
499 if (tout == NULL || tout == Py_None)
500 timeout = -1;
501 else if (!PyNumber_Check(tout)) {
502 PyErr_SetString(PyExc_TypeError,
503 "timeout must be an integer or None");
504 return NULL;
505 }
506 else {
507 tout = PyNumber_Int(tout);
508 if (!tout)
509 return NULL;
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200510 timeout = _PyInt_AsInt(tout);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000511 Py_DECREF(tout);
512 if (timeout == -1 && PyErr_Occurred())
513 return NULL;
514 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000516 /* Ensure the ufd array is up to date */
517 if (!self->ufd_uptodate)
518 if (update_ufd_array(self) == 0)
519 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000520
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000521 /* call poll() */
522 Py_BEGIN_ALLOW_THREADS
523 poll_result = poll(self->ufds, self->ufd_len, timeout);
524 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000525
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000526 if (poll_result < 0) {
527 PyErr_SetFromErrno(SelectError);
528 return NULL;
529 }
530
531 /* build the result list */
532
533 result_list = PyList_New(poll_result);
534 if (!result_list)
535 return NULL;
536 else {
537 for (i = 0, j = 0; j < poll_result; j++) {
538 /* skip to the next fired descriptor */
539 while (!self->ufds[i].revents) {
540 i++;
541 }
542 /* if we hit a NULL return, set value to NULL
543 and break out of loop; code at end will
544 clean up result_list */
545 value = PyTuple_New(2);
546 if (value == NULL)
547 goto error;
548 num = PyInt_FromLong(self->ufds[i].fd);
549 if (num == NULL) {
550 Py_DECREF(value);
551 goto error;
552 }
553 PyTuple_SET_ITEM(value, 0, num);
554
555 /* The &0xffff is a workaround for AIX. 'revents'
556 is a 16-bit short, and IBM assigned POLLNVAL
557 to be 0x8000, so the conversion to int results
558 in a negative number. See SF bug #923315. */
559 num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
560 if (num == NULL) {
561 Py_DECREF(value);
562 goto error;
563 }
564 PyTuple_SET_ITEM(value, 1, num);
565 if ((PyList_SetItem(result_list, j, value)) == -1) {
566 Py_DECREF(value);
567 goto error;
568 }
569 i++;
570 }
571 }
572 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000573
574 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000575 Py_DECREF(result_list);
576 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000577}
578
579static PyMethodDef poll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000580 {"register", (PyCFunction)poll_register,
581 METH_VARARGS, poll_register_doc},
582 {"modify", (PyCFunction)poll_modify,
583 METH_VARARGS, poll_modify_doc},
584 {"unregister", (PyCFunction)poll_unregister,
585 METH_O, poll_unregister_doc},
586 {"poll", (PyCFunction)poll_poll,
587 METH_VARARGS, poll_poll_doc},
588 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589};
590
591static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000592newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000593{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000594 pollObject *self;
595 self = PyObject_New(pollObject, &poll_Type);
596 if (self == NULL)
597 return NULL;
598 /* ufd_uptodate is a Boolean, denoting whether the
599 array pointed to by ufds matches the contents of the dictionary. */
600 self->ufd_uptodate = 0;
601 self->ufds = NULL;
602 self->dict = PyDict_New();
603 if (self->dict == NULL) {
604 Py_DECREF(self);
605 return NULL;
606 }
607 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000608}
609
610static void
611poll_dealloc(pollObject *self)
612{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000613 if (self->ufds != NULL)
614 PyMem_DEL(self->ufds);
615 Py_XDECREF(self->dict);
616 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000617}
618
619static PyObject *
620poll_getattr(pollObject *self, char *name)
621{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000622 return Py_FindMethod(poll_methods, (PyObject *)self, name);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623}
624
Tim Peters0c322792002-07-17 16:49:03 +0000625static PyTypeObject poll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000626 /* The ob_type field must be initialized in the module init function
627 * to be portable to Windows without using C++. */
628 PyVarObject_HEAD_INIT(NULL, 0)
629 "select.poll", /*tp_name*/
630 sizeof(pollObject), /*tp_basicsize*/
631 0, /*tp_itemsize*/
632 /* methods */
633 (destructor)poll_dealloc, /*tp_dealloc*/
634 0, /*tp_print*/
635 (getattrfunc)poll_getattr, /*tp_getattr*/
636 0, /*tp_setattr*/
637 0, /*tp_compare*/
638 0, /*tp_repr*/
639 0, /*tp_as_number*/
640 0, /*tp_as_sequence*/
641 0, /*tp_as_mapping*/
642 0, /*tp_hash*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000643};
644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000645PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000646"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000647unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000648
649static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +0000650select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000651{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000652 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000653}
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000654
655#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000656/*
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000657 * On some systems poll() sets errno on invalid file descriptors. We test
658 * for this at runtime because this bug may be fixed or introduced between
659 * OS releases.
660 */
661static int select_have_broken_poll(void)
662{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000663 int poll_test;
664 int filedes[2];
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000665
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000666 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000667
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000668 /* Create a file descriptor to make invalid */
669 if (pipe(filedes) < 0) {
670 return 1;
671 }
672 poll_struct.fd = filedes[0];
673 close(filedes[0]);
674 close(filedes[1]);
675 poll_test = poll(&poll_struct, 1, 0);
676 if (poll_test < 0) {
677 return 1;
678 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
679 return 1;
680 }
681 return 0;
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000682}
683#endif /* __APPLE__ */
684
685#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000686
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000687#ifdef HAVE_EPOLL
688/* **************************************************************************
689 * epoll interface for Linux 2.6
690 *
691 * Written by Christian Heimes
692 * Inspired by Twisted's _epoll.pyx and select.poll()
693 */
694
695#ifdef HAVE_SYS_EPOLL_H
696#include <sys/epoll.h>
697#endif
698
699typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000700 PyObject_HEAD
701 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000702} pyEpoll_Object;
703
704static PyTypeObject pyEpoll_Type;
705#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
706
707static PyObject *
708pyepoll_err_closed(void)
709{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000710 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
711 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000712}
713
714static int
715pyepoll_internal_close(pyEpoll_Object *self)
716{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000717 int save_errno = 0;
718 if (self->epfd >= 0) {
719 int epfd = self->epfd;
720 self->epfd = -1;
721 Py_BEGIN_ALLOW_THREADS
722 if (close(epfd) < 0)
723 save_errno = errno;
724 Py_END_ALLOW_THREADS
725 }
726 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000727}
728
729static PyObject *
730newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
731{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000732 pyEpoll_Object *self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000733
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000734 if (sizehint == -1) {
735 sizehint = FD_SETSIZE-1;
736 }
737 else if (sizehint < 1) {
738 PyErr_Format(PyExc_ValueError,
739 "sizehint must be greater zero, got %d",
740 sizehint);
741 return NULL;
742 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000743
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000744 assert(type != NULL && type->tp_alloc != NULL);
745 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
746 if (self == NULL)
747 return NULL;
748
749 if (fd == -1) {
750 Py_BEGIN_ALLOW_THREADS
751 self->epfd = epoll_create(sizehint);
752 Py_END_ALLOW_THREADS
753 }
754 else {
755 self->epfd = fd;
756 }
757 if (self->epfd < 0) {
758 Py_DECREF(self);
759 PyErr_SetFromErrno(PyExc_IOError);
760 return NULL;
761 }
762 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000763}
764
765
766static PyObject *
767pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
768{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000769 int sizehint = -1;
770 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000771
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000772 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
773 &sizehint))
774 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000775
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000776 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000777}
778
779
780static void
781pyepoll_dealloc(pyEpoll_Object *self)
782{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000783 (void)pyepoll_internal_close(self);
784 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000785}
786
787static PyObject*
788pyepoll_close(pyEpoll_Object *self)
789{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000790 errno = pyepoll_internal_close(self);
791 if (errno < 0) {
792 PyErr_SetFromErrno(PyExc_IOError);
793 return NULL;
794 }
795 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000796}
797
798PyDoc_STRVAR(pyepoll_close_doc,
799"close() -> None\n\
800\n\
801Close the epoll control file descriptor. Further operations on the epoll\n\
802object will raise an exception.");
803
804static PyObject*
805pyepoll_get_closed(pyEpoll_Object *self)
806{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000807 if (self->epfd < 0)
808 Py_RETURN_TRUE;
809 else
810 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000811}
812
813static PyObject*
814pyepoll_fileno(pyEpoll_Object *self)
815{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000816 if (self->epfd < 0)
817 return pyepoll_err_closed();
818 return PyInt_FromLong(self->epfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000819}
820
821PyDoc_STRVAR(pyepoll_fileno_doc,
822"fileno() -> int\n\
823\n\
824Return the epoll control file descriptor.");
825
826static PyObject*
827pyepoll_fromfd(PyObject *cls, PyObject *args)
828{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000829 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000830
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000831 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
832 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000833
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000834 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000835}
836
837PyDoc_STRVAR(pyepoll_fromfd_doc,
838"fromfd(fd) -> epoll\n\
839\n\
840Create an epoll object from a given control fd.");
841
842static PyObject *
843pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
844{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000845 struct epoll_event ev;
846 int result;
847 int fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000848
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000849 if (epfd < 0)
850 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000851
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000852 fd = PyObject_AsFileDescriptor(pfd);
853 if (fd == -1) {
854 return NULL;
855 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000856
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000857 switch(op) {
858 case EPOLL_CTL_ADD:
859 case EPOLL_CTL_MOD:
860 ev.events = events;
861 ev.data.fd = fd;
862 Py_BEGIN_ALLOW_THREADS
863 result = epoll_ctl(epfd, op, fd, &ev);
864 Py_END_ALLOW_THREADS
865 break;
866 case EPOLL_CTL_DEL:
867 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
868 * operation required a non-NULL pointer in event, even
869 * though this argument is ignored. */
870 Py_BEGIN_ALLOW_THREADS
871 result = epoll_ctl(epfd, op, fd, &ev);
872 if (errno == EBADF) {
873 /* fd already closed */
874 result = 0;
875 errno = 0;
876 }
877 Py_END_ALLOW_THREADS
878 break;
879 default:
880 result = -1;
881 errno = EINVAL;
882 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000883
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000884 if (result < 0) {
885 PyErr_SetFromErrno(PyExc_IOError);
886 return NULL;
887 }
888 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000889}
890
891static PyObject *
892pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
893{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000894 PyObject *pfd;
895 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
896 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000897
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000898 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
899 &pfd, &events)) {
900 return NULL;
901 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000902
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000903 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000904}
905
906PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl7d4bfb32010-08-02 21:44:25 +0000907"register(fd[, eventmask]) -> None\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000908\n\
Senthil Kumaran2bd91002011-06-26 23:50:35 -0700909Registers a new fd or raises an IOError if the fd is already registered.\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000910fd is the target file descriptor of the operation.\n\
911events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000912is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
913\n\
914The epoll interface supports all file descriptors that support poll.");
915
916static PyObject *
917pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
918{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000919 PyObject *pfd;
920 unsigned int events;
921 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000922
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000923 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
924 &pfd, &events)) {
925 return NULL;
926 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000927
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000928 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000929}
930
931PyDoc_STRVAR(pyepoll_modify_doc,
932"modify(fd, eventmask) -> None\n\
933\n\
934fd is the target file descriptor of the operation\n\
935events is a bit set composed of the various EPOLL constants");
936
937static PyObject *
938pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
939{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000940 PyObject *pfd;
941 static char *kwlist[] = {"fd", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000942
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000943 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
944 &pfd)) {
945 return NULL;
946 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000947
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000948 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000949}
950
951PyDoc_STRVAR(pyepoll_unregister_doc,
952"unregister(fd) -> None\n\
953\n\
954fd is the target file descriptor of the operation.");
955
956static PyObject *
957pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
958{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000959 double dtimeout = -1.;
960 int timeout;
961 int maxevents = -1;
962 int nfds, i;
963 PyObject *elist = NULL, *etuple = NULL;
964 struct epoll_event *evs = NULL;
965 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000966
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 if (self->epfd < 0)
968 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000969
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000970 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
971 &dtimeout, &maxevents)) {
972 return NULL;
973 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000974
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000975 if (dtimeout < 0) {
976 timeout = -1;
977 }
978 else if (dtimeout * 1000.0 > INT_MAX) {
979 PyErr_SetString(PyExc_OverflowError,
980 "timeout is too large");
981 return NULL;
982 }
983 else {
984 timeout = (int)(dtimeout * 1000.0);
985 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000986
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000987 if (maxevents == -1) {
988 maxevents = FD_SETSIZE-1;
989 }
990 else if (maxevents < 1) {
991 PyErr_Format(PyExc_ValueError,
992 "maxevents must be greater than 0, got %d",
993 maxevents);
994 return NULL;
995 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000996
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000997 evs = PyMem_New(struct epoll_event, maxevents);
998 if (evs == NULL) {
999 Py_DECREF(self);
1000 PyErr_NoMemory();
1001 return NULL;
1002 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001003
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001004 Py_BEGIN_ALLOW_THREADS
1005 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1006 Py_END_ALLOW_THREADS
1007 if (nfds < 0) {
1008 PyErr_SetFromErrno(PyExc_IOError);
1009 goto error;
1010 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001011
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001012 elist = PyList_New(nfds);
1013 if (elist == NULL) {
1014 goto error;
1015 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001016
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001017 for (i = 0; i < nfds; i++) {
1018 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1019 if (etuple == NULL) {
1020 Py_CLEAR(elist);
1021 goto error;
1022 }
1023 PyList_SET_ITEM(elist, i, etuple);
1024 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001025
Georg Brandl018a3622008-03-26 12:57:47 +00001026 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001027 PyMem_Free(evs);
1028 return elist;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001029}
1030
1031PyDoc_STRVAR(pyepoll_poll_doc,
1032"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1033\n\
1034Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1035in seconds (as float). -1 makes poll wait indefinitely.\n\
1036Up to maxevents are returned to the caller.");
1037
1038static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001039 {"fromfd", (PyCFunction)pyepoll_fromfd,
1040 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1041 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1042 pyepoll_close_doc},
1043 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1044 pyepoll_fileno_doc},
1045 {"modify", (PyCFunction)pyepoll_modify,
1046 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1047 {"register", (PyCFunction)pyepoll_register,
1048 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1049 {"unregister", (PyCFunction)pyepoll_unregister,
1050 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1051 {"poll", (PyCFunction)pyepoll_poll,
1052 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1053 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001054};
1055
1056static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001057 {"closed", (getter)pyepoll_get_closed, NULL,
1058 "True if the epoll handler is closed"},
1059 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001060};
1061
1062PyDoc_STRVAR(pyepoll_doc,
1063"select.epoll([sizehint=-1])\n\
1064\n\
1065Returns an epolling object\n\
1066\n\
1067sizehint must be a positive integer or -1 for the default size. The\n\
1068sizehint is used to optimize internal data structures. It doesn't limit\n\
1069the maximum number of monitored events.");
1070
1071static PyTypeObject pyEpoll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001072 PyVarObject_HEAD_INIT(NULL, 0)
1073 "select.epoll", /* tp_name */
1074 sizeof(pyEpoll_Object), /* tp_basicsize */
1075 0, /* tp_itemsize */
1076 (destructor)pyepoll_dealloc, /* tp_dealloc */
1077 0, /* tp_print */
1078 0, /* tp_getattr */
1079 0, /* tp_setattr */
1080 0, /* tp_compare */
1081 0, /* tp_repr */
1082 0, /* tp_as_number */
1083 0, /* tp_as_sequence */
1084 0, /* tp_as_mapping */
1085 0, /* tp_hash */
1086 0, /* tp_call */
1087 0, /* tp_str */
1088 PyObject_GenericGetAttr, /* tp_getattro */
1089 0, /* tp_setattro */
1090 0, /* tp_as_buffer */
1091 Py_TPFLAGS_DEFAULT, /* tp_flags */
1092 pyepoll_doc, /* tp_doc */
1093 0, /* tp_traverse */
1094 0, /* tp_clear */
1095 0, /* tp_richcompare */
1096 0, /* tp_weaklistoffset */
1097 0, /* tp_iter */
1098 0, /* tp_iternext */
1099 pyepoll_methods, /* tp_methods */
1100 0, /* tp_members */
1101 pyepoll_getsetlist, /* tp_getset */
1102 0, /* tp_base */
1103 0, /* tp_dict */
1104 0, /* tp_descr_get */
1105 0, /* tp_descr_set */
1106 0, /* tp_dictoffset */
1107 0, /* tp_init */
1108 0, /* tp_alloc */
1109 pyepoll_new, /* tp_new */
1110 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001111};
1112
1113#endif /* HAVE_EPOLL */
1114
1115#ifdef HAVE_KQUEUE
1116/* **************************************************************************
1117 * kqueue interface for BSD
1118 *
1119 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1120 * All rights reserved.
1121 *
1122 * Redistribution and use in source and binary forms, with or without
1123 * modification, are permitted provided that the following conditions
1124 * are met:
1125 * 1. Redistributions of source code must retain the above copyright
1126 * notice, this list of conditions and the following disclaimer.
1127 * 2. Redistributions in binary form must reproduce the above copyright
1128 * notice, this list of conditions and the following disclaimer in the
1129 * documentation and/or other materials provided with the distribution.
1130 *
1131 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1132 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1133 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1134 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1135 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1136 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1137 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1138 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1139 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1140 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1141 * SUCH DAMAGE.
1142 */
1143
1144#ifdef HAVE_SYS_EVENT_H
1145#include <sys/event.h>
1146#endif
1147
1148PyDoc_STRVAR(kqueue_event_doc,
Georg Brandlfa1ffb62009-12-29 21:09:17 +00001149"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001150\n\
1151This object is the equivalent of the struct kevent for the C API.\n\
1152\n\
1153See the kqueue manpage for more detailed information about the meaning\n\
1154of the arguments.\n\
1155\n\
1156One minor note: while you might hope that udata could store a\n\
1157reference to a python object, it cannot, because it is impossible to\n\
1158keep a proper reference count of the object once it's passed into the\n\
1159kernel. Therefore, I have restricted it to only storing an integer. I\n\
1160recommend ignoring it and simply using the 'ident' field to key off\n\
1161of. You could also set up a dictionary on the python side to store a\n\
1162udata->object mapping.");
1163
1164typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001165 PyObject_HEAD
1166 struct kevent e;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001167} kqueue_event_Object;
1168
1169static PyTypeObject kqueue_event_Type;
1170
1171#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1172
1173typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001174 PyObject_HEAD
1175 SOCKET kqfd; /* kqueue control fd */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001176} kqueue_queue_Object;
1177
1178static PyTypeObject kqueue_queue_Type;
1179
1180#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1181
Antoine Pitrou323b9da2009-11-04 19:25:14 +00001182#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1183# error uintptr_t does not match void *!
1184#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1185# define T_UINTPTRT T_ULONGLONG
1186# define T_INTPTRT T_LONGLONG
1187# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1188# define UINTPTRT_FMT_UNIT "K"
1189# define INTPTRT_FMT_UNIT "L"
1190#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1191# define T_UINTPTRT T_ULONG
1192# define T_INTPTRT T_LONG
1193# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1194# define UINTPTRT_FMT_UNIT "k"
1195# define INTPTRT_FMT_UNIT "l"
1196#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1197# define T_UINTPTRT T_UINT
1198# define T_INTPTRT T_INT
1199# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1200# define UINTPTRT_FMT_UNIT "I"
1201# define INTPTRT_FMT_UNIT "i"
1202#else
1203# error uintptr_t does not match int, long, or long long!
1204#endif
1205
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001206/* Unfortunately, we can't store python objects in udata, because
1207 * kevents in the kernel can be removed without warning, which would
1208 * forever lose the refcount on the object stored with it.
1209 */
1210
1211#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1212static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001213 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1214 {"filter", T_SHORT, KQ_OFF(e.filter)},
1215 {"flags", T_USHORT, KQ_OFF(e.flags)},
1216 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1217 {"data", T_INTPTRT, KQ_OFF(e.data)},
1218 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1219 {NULL} /* Sentinel */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001220};
1221#undef KQ_OFF
1222
1223static PyObject *
Georg Brandlea370a92010-02-23 21:48:57 +00001224
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001225kqueue_event_repr(kqueue_event_Object *s)
1226{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001227 char buf[1024];
1228 PyOS_snprintf(
1229 buf, sizeof(buf),
1230 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1231 "data=0x%zd udata=%p>",
1232 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1233 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1234 return PyString_FromString(buf);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001235}
1236
1237static int
1238kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1239{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001240 PyObject *pfd;
1241 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1242 "data", "udata", NULL};
1243 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001244
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001245 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001246
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001247 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1248 &pfd, &(self->e.filter), &(self->e.flags),
1249 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1250 return -1;
1251 }
1252
1253 if (PyLong_Check(pfd)) {
1254 self->e.ident = PyLong_AsUintptr_t(pfd);
1255 }
1256 else {
1257 self->e.ident = PyObject_AsFileDescriptor(pfd);
1258 }
1259 if (PyErr_Occurred()) {
1260 return -1;
1261 }
1262 return 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001263}
1264
1265static PyObject *
1266kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001267 int op)
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001268{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001269 Py_intptr_t result = 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001270
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001271 if (!kqueue_event_Check(o)) {
1272 if (op == Py_EQ || op == Py_NE) {
1273 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1274 Py_INCREF(res);
1275 return res;
1276 }
1277 PyErr_Format(PyExc_TypeError,
1278 "can't compare %.200s to %.200s",
1279 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1280 return NULL;
1281 }
1282 if (((result = s->e.ident - o->e.ident) == 0) &&
1283 ((result = s->e.filter - o->e.filter) == 0) &&
1284 ((result = s->e.flags - o->e.flags) == 0) &&
1285 ((result = s->e.fflags - o->e.fflags) == 0) &&
1286 ((result = s->e.data - o->e.data) == 0) &&
1287 ((result = s->e.udata - o->e.udata) == 0)
1288 ) {
1289 result = 0;
1290 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001291
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001292 switch (op) {
1293 case Py_EQ:
1294 result = (result == 0);
1295 break;
1296 case Py_NE:
1297 result = (result != 0);
1298 break;
1299 case Py_LE:
1300 result = (result <= 0);
1301 break;
1302 case Py_GE:
1303 result = (result >= 0);
1304 break;
1305 case Py_LT:
1306 result = (result < 0);
1307 break;
1308 case Py_GT:
1309 result = (result > 0);
1310 break;
1311 }
1312 return PyBool_FromLong((long)result);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001313}
1314
1315static PyTypeObject kqueue_event_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001316 PyVarObject_HEAD_INIT(NULL, 0)
1317 "select.kevent", /* tp_name */
1318 sizeof(kqueue_event_Object), /* tp_basicsize */
1319 0, /* tp_itemsize */
1320 0, /* tp_dealloc */
1321 0, /* tp_print */
1322 0, /* tp_getattr */
1323 0, /* tp_setattr */
1324 0, /* tp_compare */
1325 (reprfunc)kqueue_event_repr, /* tp_repr */
1326 0, /* tp_as_number */
1327 0, /* tp_as_sequence */
1328 0, /* tp_as_mapping */
1329 0, /* tp_hash */
1330 0, /* tp_call */
1331 0, /* tp_str */
1332 0, /* tp_getattro */
1333 0, /* tp_setattro */
1334 0, /* tp_as_buffer */
1335 Py_TPFLAGS_DEFAULT, /* tp_flags */
1336 kqueue_event_doc, /* tp_doc */
1337 0, /* tp_traverse */
1338 0, /* tp_clear */
1339 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1340 0, /* tp_weaklistoffset */
1341 0, /* tp_iter */
1342 0, /* tp_iternext */
1343 0, /* tp_methods */
1344 kqueue_event_members, /* tp_members */
1345 0, /* tp_getset */
1346 0, /* tp_base */
1347 0, /* tp_dict */
1348 0, /* tp_descr_get */
1349 0, /* tp_descr_set */
1350 0, /* tp_dictoffset */
1351 (initproc)kqueue_event_init, /* tp_init */
1352 0, /* tp_alloc */
1353 0, /* tp_new */
1354 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001355};
1356
1357static PyObject *
1358kqueue_queue_err_closed(void)
1359{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001360 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1361 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001362}
1363
1364static int
1365kqueue_queue_internal_close(kqueue_queue_Object *self)
1366{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001367 int save_errno = 0;
1368 if (self->kqfd >= 0) {
1369 int kqfd = self->kqfd;
1370 self->kqfd = -1;
1371 Py_BEGIN_ALLOW_THREADS
1372 if (close(kqfd) < 0)
1373 save_errno = errno;
1374 Py_END_ALLOW_THREADS
1375 }
1376 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001377}
1378
1379static PyObject *
1380newKqueue_Object(PyTypeObject *type, SOCKET fd)
1381{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001382 kqueue_queue_Object *self;
1383 assert(type != NULL && type->tp_alloc != NULL);
1384 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1385 if (self == NULL) {
1386 return NULL;
1387 }
1388
1389 if (fd == -1) {
1390 Py_BEGIN_ALLOW_THREADS
1391 self->kqfd = kqueue();
1392 Py_END_ALLOW_THREADS
1393 }
1394 else {
1395 self->kqfd = fd;
1396 }
1397 if (self->kqfd < 0) {
1398 Py_DECREF(self);
1399 PyErr_SetFromErrno(PyExc_IOError);
1400 return NULL;
1401 }
1402 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001403}
1404
1405static PyObject *
1406kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1407{
1408
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001409 if ((args != NULL && PyObject_Size(args)) ||
1410 (kwds != NULL && PyObject_Size(kwds))) {
1411 PyErr_SetString(PyExc_ValueError,
1412 "select.kqueue doesn't accept arguments");
1413 return NULL;
1414 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001415
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001416 return newKqueue_Object(type, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001417}
1418
1419static void
1420kqueue_queue_dealloc(kqueue_queue_Object *self)
1421{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001422 kqueue_queue_internal_close(self);
1423 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001424}
1425
1426static PyObject*
1427kqueue_queue_close(kqueue_queue_Object *self)
1428{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001429 errno = kqueue_queue_internal_close(self);
1430 if (errno < 0) {
1431 PyErr_SetFromErrno(PyExc_IOError);
1432 return NULL;
1433 }
1434 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001435}
1436
1437PyDoc_STRVAR(kqueue_queue_close_doc,
1438"close() -> None\n\
1439\n\
1440Close the kqueue control file descriptor. Further operations on the kqueue\n\
1441object will raise an exception.");
1442
1443static PyObject*
1444kqueue_queue_get_closed(kqueue_queue_Object *self)
1445{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001446 if (self->kqfd < 0)
1447 Py_RETURN_TRUE;
1448 else
1449 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001450}
1451
1452static PyObject*
1453kqueue_queue_fileno(kqueue_queue_Object *self)
1454{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001455 if (self->kqfd < 0)
1456 return kqueue_queue_err_closed();
1457 return PyInt_FromLong(self->kqfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001458}
1459
1460PyDoc_STRVAR(kqueue_queue_fileno_doc,
1461"fileno() -> int\n\
1462\n\
1463Return the kqueue control file descriptor.");
1464
1465static PyObject*
1466kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1467{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001468 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001469
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001470 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1471 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001472
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001473 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001474}
1475
1476PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1477"fromfd(fd) -> kqueue\n\
1478\n\
1479Create a kqueue object from a given control fd.");
1480
1481static PyObject *
1482kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1483{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001484 int nevents = 0;
1485 int gotevents = 0;
1486 int nchanges = 0;
1487 int i = 0;
1488 PyObject *otimeout = NULL;
1489 PyObject *ch = NULL;
1490 PyObject *it = NULL, *ei = NULL;
1491 PyObject *result = NULL;
1492 struct kevent *evl = NULL;
1493 struct kevent *chl = NULL;
1494 struct timespec timeoutspec;
1495 struct timespec *ptimeoutspec;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001496
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001497 if (self->kqfd < 0)
1498 return kqueue_queue_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001499
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001500 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1501 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001502
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001503 if (nevents < 0) {
1504 PyErr_Format(PyExc_ValueError,
1505 "Length of eventlist must be 0 or positive, got %d",
1506 nevents);
1507 return NULL;
1508 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001509
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001510 if (otimeout == Py_None || otimeout == NULL) {
1511 ptimeoutspec = NULL;
1512 }
1513 else if (PyNumber_Check(otimeout)) {
1514 double timeout;
1515 long seconds;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001516
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001517 timeout = PyFloat_AsDouble(otimeout);
1518 if (timeout == -1 && PyErr_Occurred())
1519 return NULL;
1520 if (timeout > (double)LONG_MAX) {
1521 PyErr_SetString(PyExc_OverflowError,
1522 "timeout period too long");
1523 return NULL;
1524 }
1525 if (timeout < 0) {
1526 PyErr_SetString(PyExc_ValueError,
1527 "timeout must be positive or None");
1528 return NULL;
1529 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001530
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001531 seconds = (long)timeout;
1532 timeout = timeout - (double)seconds;
1533 timeoutspec.tv_sec = seconds;
1534 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1535 ptimeoutspec = &timeoutspec;
1536 }
1537 else {
1538 PyErr_Format(PyExc_TypeError,
1539 "timeout argument must be an number "
1540 "or None, got %.200s",
1541 Py_TYPE(otimeout)->tp_name);
1542 return NULL;
1543 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001544
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001545 if (ch != NULL && ch != Py_None) {
1546 it = PyObject_GetIter(ch);
1547 if (it == NULL) {
1548 PyErr_SetString(PyExc_TypeError,
1549 "changelist is not iterable");
1550 return NULL;
1551 }
1552 nchanges = PyObject_Size(ch);
1553 if (nchanges < 0) {
1554 goto error;
1555 }
Georg Brandlea370a92010-02-23 21:48:57 +00001556
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001557 chl = PyMem_New(struct kevent, nchanges);
1558 if (chl == NULL) {
1559 PyErr_NoMemory();
1560 goto error;
1561 }
1562 i = 0;
1563 while ((ei = PyIter_Next(it)) != NULL) {
1564 if (!kqueue_event_Check(ei)) {
1565 Py_DECREF(ei);
1566 PyErr_SetString(PyExc_TypeError,
1567 "changelist must be an iterable of "
1568 "select.kevent objects");
1569 goto error;
1570 } else {
1571 chl[i++] = ((kqueue_event_Object *)ei)->e;
1572 }
1573 Py_DECREF(ei);
1574 }
1575 }
1576 Py_CLEAR(it);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001577
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001578 /* event list */
1579 if (nevents) {
1580 evl = PyMem_New(struct kevent, nevents);
1581 if (evl == NULL) {
1582 PyErr_NoMemory();
1583 goto error;
1584 }
1585 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001586
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001587 Py_BEGIN_ALLOW_THREADS
1588 gotevents = kevent(self->kqfd, chl, nchanges,
1589 evl, nevents, ptimeoutspec);
1590 Py_END_ALLOW_THREADS
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001591
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001592 if (gotevents == -1) {
1593 PyErr_SetFromErrno(PyExc_OSError);
1594 goto error;
1595 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001596
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001597 result = PyList_New(gotevents);
1598 if (result == NULL) {
1599 goto error;
1600 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001601
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001602 for (i = 0; i < gotevents; i++) {
1603 kqueue_event_Object *ch;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001604
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001605 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1606 if (ch == NULL) {
1607 goto error;
1608 }
1609 ch->e = evl[i];
1610 PyList_SET_ITEM(result, i, (PyObject *)ch);
1611 }
1612 PyMem_Free(chl);
1613 PyMem_Free(evl);
1614 return result;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001615
1616 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001617 PyMem_Free(chl);
1618 PyMem_Free(evl);
1619 Py_XDECREF(result);
1620 Py_XDECREF(it);
1621 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001622}
1623
1624PyDoc_STRVAR(kqueue_queue_control_doc,
Georg Brandl2f3bd832008-09-21 07:14:44 +00001625"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001626\n\
1627Calls the kernel kevent function.\n\
1628- changelist must be a list of kevent objects describing the changes\n\
1629 to be made to the kernel's watch list or None.\n\
1630- max_events lets you specify the maximum number of events that the\n\
1631 kernel will return.\n\
1632- timeout is the maximum time to wait in seconds, or else None,\n\
1633 to wait forever. timeout accepts floats for smaller timeouts, too.");
1634
1635
1636static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001637 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1638 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1639 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1640 kqueue_queue_close_doc},
1641 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1642 kqueue_queue_fileno_doc},
1643 {"control", (PyCFunction)kqueue_queue_control,
1644 METH_VARARGS , kqueue_queue_control_doc},
1645 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001646};
1647
1648static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001649 {"closed", (getter)kqueue_queue_get_closed, NULL,
1650 "True if the kqueue handler is closed"},
1651 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001652};
1653
1654PyDoc_STRVAR(kqueue_queue_doc,
1655"Kqueue syscall wrapper.\n\
1656\n\
1657For example, to start watching a socket for input:\n\
1658>>> kq = kqueue()\n\
1659>>> sock = socket()\n\
1660>>> sock.connect((host, port))\n\
1661>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1662\n\
1663To wait one second for it to become writeable:\n\
1664>>> kq.control(None, 1, 1000)\n\
1665\n\
1666To stop listening:\n\
1667>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1668
1669static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001670 PyVarObject_HEAD_INIT(NULL, 0)
1671 "select.kqueue", /* tp_name */
1672 sizeof(kqueue_queue_Object), /* tp_basicsize */
1673 0, /* tp_itemsize */
1674 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1675 0, /* tp_print */
1676 0, /* tp_getattr */
1677 0, /* tp_setattr */
1678 0, /* tp_compare */
1679 0, /* tp_repr */
1680 0, /* tp_as_number */
1681 0, /* tp_as_sequence */
1682 0, /* tp_as_mapping */
1683 0, /* tp_hash */
1684 0, /* tp_call */
1685 0, /* tp_str */
1686 0, /* tp_getattro */
1687 0, /* tp_setattro */
1688 0, /* tp_as_buffer */
1689 Py_TPFLAGS_DEFAULT, /* tp_flags */
1690 kqueue_queue_doc, /* tp_doc */
1691 0, /* tp_traverse */
1692 0, /* tp_clear */
1693 0, /* tp_richcompare */
1694 0, /* tp_weaklistoffset */
1695 0, /* tp_iter */
1696 0, /* tp_iternext */
1697 kqueue_queue_methods, /* tp_methods */
1698 0, /* tp_members */
1699 kqueue_queue_getsetlist, /* tp_getset */
1700 0, /* tp_base */
1701 0, /* tp_dict */
1702 0, /* tp_descr_get */
1703 0, /* tp_descr_set */
1704 0, /* tp_dictoffset */
1705 0, /* tp_init */
1706 0, /* tp_alloc */
1707 kqueue_queue_new, /* tp_new */
1708 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001709};
1710
1711#endif /* HAVE_KQUEUE */
1712/* ************************************************************************ */
1713
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001714PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001715"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1716\n\
1717Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001718The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001719rlist -- wait until ready for reading\n\
1720wlist -- wait until ready for writing\n\
1721xlist -- wait for an ``exceptional condition''\n\
1722If only one kind of condition is required, pass [] for the other lists.\n\
1723A file descriptor is either a socket or file object, or a small integer\n\
1724gotten from a fileno() method call on one of those.\n\
1725\n\
1726The optional 4th argument specifies a timeout in seconds; it may be\n\
1727a floating point number to specify fractions of seconds. If it is absent\n\
1728or None, the call will never time out.\n\
1729\n\
1730The return value is a tuple of three lists corresponding to the first three\n\
1731arguments; each contains the subset of the corresponding file descriptors\n\
1732that are ready.\n\
1733\n\
1734*** IMPORTANT NOTICE ***\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001735On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +00001736descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001737
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001738static PyMethodDef select_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001739 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natalia41cf292013-01-19 12:15:56 +01001740#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001741 {"poll", select_poll, METH_NOARGS, poll_doc},
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001742#endif /* HAVE_POLL */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001743 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001744};
1745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001746PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001747"This module supports asynchronous I/O on multiple file descriptors.\n\
1748\n\
1749*** IMPORTANT NOTICE ***\n\
Neal Norwitz2a30cd02006-07-10 01:18:57 +00001750On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001751
Mark Hammond62b1ab12002-07-23 06:31:15 +00001752PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001753initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001754{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001755 PyObject *m;
1756 m = Py_InitModule3("select", select_methods, module_doc);
1757 if (m == NULL)
1758 return;
Fred Drake4baedc12002-04-01 14:53:37 +00001759
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001760 SelectError = PyErr_NewException("select.error", NULL, NULL);
1761 Py_INCREF(SelectError);
1762 PyModule_AddObject(m, "error", SelectError);
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001763
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001764#ifdef PIPE_BUF
R. David Murray1d9d16e2010-10-16 00:43:13 +00001765#ifdef HAVE_BROKEN_PIPE_BUF
1766#undef PIPE_BUF
1767#define PIPE_BUF 512
1768#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001769 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001770#endif
Gregory P. Smith9d36fd22009-07-03 20:48:31 +00001771
Charles-François Natalia41cf292013-01-19 12:15:56 +01001772#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001773#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001774 if (select_have_broken_poll()) {
1775 if (PyObject_DelAttrString(m, "poll") == -1) {
1776 PyErr_Clear();
1777 }
1778 } else {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001779#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001780 {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001781#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001782 Py_TYPE(&poll_Type) = &PyType_Type;
1783 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1784 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1785 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1786 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1787 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1788 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001789
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001790#ifdef POLLRDNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001791 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001792#endif
1793#ifdef POLLRDBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001794 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001795#endif
1796#ifdef POLLWRNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001797 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001798#endif
1799#ifdef POLLWRBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001800 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001801#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001802#ifdef POLLMSG
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001803 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001804#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001805 }
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001806#endif /* HAVE_POLL */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001807
1808#ifdef HAVE_EPOLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001809 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1810 if (PyType_Ready(&pyEpoll_Type) < 0)
1811 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001812
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001813 Py_INCREF(&pyEpoll_Type);
1814 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001815
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001816 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1817 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1818 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1819 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1820 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1821 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001822#ifdef EPOLLONESHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001823 /* Kernel 2.6.2+ */
1824 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001825#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001826 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1827 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1828 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1829 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1830 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1831 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001832#endif /* HAVE_EPOLL */
1833
1834#ifdef HAVE_KQUEUE
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001835 kqueue_event_Type.tp_new = PyType_GenericNew;
1836 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1837 if(PyType_Ready(&kqueue_event_Type) < 0)
1838 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001839
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001840 Py_INCREF(&kqueue_event_Type);
1841 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001842
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001843 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1844 if(PyType_Ready(&kqueue_queue_Type) < 0)
1845 return;
1846 Py_INCREF(&kqueue_queue_Type);
1847 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1848
1849 /* event filters */
1850 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1851 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1852 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1853 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1854 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001855#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001856 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001857#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001858 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1859 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001860
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001861 /* event flags */
1862 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1863 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1864 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1865 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1866 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1867 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001868
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001869 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1870 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001871
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001872 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1873 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001874
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001875 /* READ WRITE filter flag */
1876 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001877
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001878 /* VNODE filter flags */
1879 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1880 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1881 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1882 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1883 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1884 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1885 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001886
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001887 /* PROC filter flags */
1888 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1889 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1890 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1891 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1892 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001893
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001894 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1895 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1896 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1897
1898 /* NETDEV filter flags */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001899#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001900 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001903#endif
1904
1905#endif /* HAVE_KQUEUE */
Guido van Rossumed233a51992-06-23 09:07:03 +00001906}