blob: 4cbf885b18fee312d27e57caca9456518e53c055 [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
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001206/*
1207 * kevent is not standard and its members vary across BSDs.
1208 */
1209#if !defined(__OpenBSD__)
1210# define IDENT_TYPE T_UINTPTRT
1211# define IDENT_CAST Py_intptr_t
1212# define DATA_TYPE T_INTPTRT
1213# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1214# define IDENT_AsType PyLong_AsUintptr_t
1215#else
1216# define IDENT_TYPE T_UINT
1217# define IDENT_CAST int
1218# define DATA_TYPE T_INT
1219# define DATA_FMT_UNIT "i"
1220# define IDENT_AsType PyLong_AsUnsignedLong
1221#endif
1222
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001223/* Unfortunately, we can't store python objects in udata, because
1224 * kevents in the kernel can be removed without warning, which would
1225 * forever lose the refcount on the object stored with it.
1226 */
1227
1228#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1229static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001230 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001231 {"filter", T_SHORT, KQ_OFF(e.filter)},
1232 {"flags", T_USHORT, KQ_OFF(e.flags)},
1233 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001234 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001235 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1236 {NULL} /* Sentinel */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001237};
1238#undef KQ_OFF
1239
1240static PyObject *
Georg Brandlea370a92010-02-23 21:48:57 +00001241
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001242kqueue_event_repr(kqueue_event_Object *s)
1243{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001244 char buf[1024];
1245 PyOS_snprintf(
1246 buf, sizeof(buf),
1247 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1248 "data=0x%zd udata=%p>",
1249 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1250 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1251 return PyString_FromString(buf);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001252}
1253
1254static int
1255kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1256{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001257 PyObject *pfd;
1258 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1259 "data", "udata", NULL};
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001260 static char *fmt = "O|hhi" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001261
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001262 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001263
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001264 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1265 &pfd, &(self->e.filter), &(self->e.flags),
1266 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1267 return -1;
1268 }
1269
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001270 if (PyLong_Check(pfd)
1271#if IDENT_TYPE == T_UINT
1272 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1273#endif
1274 ) {
1275 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001276 }
1277 else {
1278 self->e.ident = PyObject_AsFileDescriptor(pfd);
1279 }
1280 if (PyErr_Occurred()) {
1281 return -1;
1282 }
1283 return 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001284}
1285
1286static PyObject *
1287kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001288 int op)
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001289{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001290 Py_intptr_t result = 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001291
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001292 if (!kqueue_event_Check(o)) {
1293 if (op == Py_EQ || op == Py_NE) {
1294 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1295 Py_INCREF(res);
1296 return res;
1297 }
1298 PyErr_Format(PyExc_TypeError,
1299 "can't compare %.200s to %.200s",
1300 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1301 return NULL;
1302 }
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001303 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001304 ((result = s->e.filter - o->e.filter) == 0) &&
1305 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001306 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001307 ((result = s->e.data - o->e.data) == 0) &&
1308 ((result = s->e.udata - o->e.udata) == 0)
1309 ) {
1310 result = 0;
1311 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001312
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001313 switch (op) {
1314 case Py_EQ:
1315 result = (result == 0);
1316 break;
1317 case Py_NE:
1318 result = (result != 0);
1319 break;
1320 case Py_LE:
1321 result = (result <= 0);
1322 break;
1323 case Py_GE:
1324 result = (result >= 0);
1325 break;
1326 case Py_LT:
1327 result = (result < 0);
1328 break;
1329 case Py_GT:
1330 result = (result > 0);
1331 break;
1332 }
1333 return PyBool_FromLong((long)result);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001334}
1335
1336static PyTypeObject kqueue_event_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001337 PyVarObject_HEAD_INIT(NULL, 0)
1338 "select.kevent", /* tp_name */
1339 sizeof(kqueue_event_Object), /* tp_basicsize */
1340 0, /* tp_itemsize */
1341 0, /* tp_dealloc */
1342 0, /* tp_print */
1343 0, /* tp_getattr */
1344 0, /* tp_setattr */
1345 0, /* tp_compare */
1346 (reprfunc)kqueue_event_repr, /* tp_repr */
1347 0, /* tp_as_number */
1348 0, /* tp_as_sequence */
1349 0, /* tp_as_mapping */
1350 0, /* tp_hash */
1351 0, /* tp_call */
1352 0, /* tp_str */
1353 0, /* tp_getattro */
1354 0, /* tp_setattro */
1355 0, /* tp_as_buffer */
1356 Py_TPFLAGS_DEFAULT, /* tp_flags */
1357 kqueue_event_doc, /* tp_doc */
1358 0, /* tp_traverse */
1359 0, /* tp_clear */
1360 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1361 0, /* tp_weaklistoffset */
1362 0, /* tp_iter */
1363 0, /* tp_iternext */
1364 0, /* tp_methods */
1365 kqueue_event_members, /* tp_members */
1366 0, /* tp_getset */
1367 0, /* tp_base */
1368 0, /* tp_dict */
1369 0, /* tp_descr_get */
1370 0, /* tp_descr_set */
1371 0, /* tp_dictoffset */
1372 (initproc)kqueue_event_init, /* tp_init */
1373 0, /* tp_alloc */
1374 0, /* tp_new */
1375 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001376};
1377
1378static PyObject *
1379kqueue_queue_err_closed(void)
1380{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001381 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1382 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001383}
1384
1385static int
1386kqueue_queue_internal_close(kqueue_queue_Object *self)
1387{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001388 int save_errno = 0;
1389 if (self->kqfd >= 0) {
1390 int kqfd = self->kqfd;
1391 self->kqfd = -1;
1392 Py_BEGIN_ALLOW_THREADS
1393 if (close(kqfd) < 0)
1394 save_errno = errno;
1395 Py_END_ALLOW_THREADS
1396 }
1397 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001398}
1399
1400static PyObject *
1401newKqueue_Object(PyTypeObject *type, SOCKET fd)
1402{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001403 kqueue_queue_Object *self;
1404 assert(type != NULL && type->tp_alloc != NULL);
1405 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1406 if (self == NULL) {
1407 return NULL;
1408 }
1409
1410 if (fd == -1) {
1411 Py_BEGIN_ALLOW_THREADS
1412 self->kqfd = kqueue();
1413 Py_END_ALLOW_THREADS
1414 }
1415 else {
1416 self->kqfd = fd;
1417 }
1418 if (self->kqfd < 0) {
1419 Py_DECREF(self);
1420 PyErr_SetFromErrno(PyExc_IOError);
1421 return NULL;
1422 }
1423 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001424}
1425
1426static PyObject *
1427kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1428{
1429
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001430 if ((args != NULL && PyObject_Size(args)) ||
1431 (kwds != NULL && PyObject_Size(kwds))) {
1432 PyErr_SetString(PyExc_ValueError,
1433 "select.kqueue doesn't accept arguments");
1434 return NULL;
1435 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001436
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001437 return newKqueue_Object(type, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001438}
1439
1440static void
1441kqueue_queue_dealloc(kqueue_queue_Object *self)
1442{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001443 kqueue_queue_internal_close(self);
1444 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001445}
1446
1447static PyObject*
1448kqueue_queue_close(kqueue_queue_Object *self)
1449{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001450 errno = kqueue_queue_internal_close(self);
1451 if (errno < 0) {
1452 PyErr_SetFromErrno(PyExc_IOError);
1453 return NULL;
1454 }
1455 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001456}
1457
1458PyDoc_STRVAR(kqueue_queue_close_doc,
1459"close() -> None\n\
1460\n\
1461Close the kqueue control file descriptor. Further operations on the kqueue\n\
1462object will raise an exception.");
1463
1464static PyObject*
1465kqueue_queue_get_closed(kqueue_queue_Object *self)
1466{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001467 if (self->kqfd < 0)
1468 Py_RETURN_TRUE;
1469 else
1470 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001471}
1472
1473static PyObject*
1474kqueue_queue_fileno(kqueue_queue_Object *self)
1475{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001476 if (self->kqfd < 0)
1477 return kqueue_queue_err_closed();
1478 return PyInt_FromLong(self->kqfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001479}
1480
1481PyDoc_STRVAR(kqueue_queue_fileno_doc,
1482"fileno() -> int\n\
1483\n\
1484Return the kqueue control file descriptor.");
1485
1486static PyObject*
1487kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1488{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001489 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001490
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001491 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1492 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001493
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001494 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001495}
1496
1497PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1498"fromfd(fd) -> kqueue\n\
1499\n\
1500Create a kqueue object from a given control fd.");
1501
1502static PyObject *
1503kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1504{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001505 int nevents = 0;
1506 int gotevents = 0;
1507 int nchanges = 0;
1508 int i = 0;
1509 PyObject *otimeout = NULL;
1510 PyObject *ch = NULL;
1511 PyObject *it = NULL, *ei = NULL;
1512 PyObject *result = NULL;
1513 struct kevent *evl = NULL;
1514 struct kevent *chl = NULL;
1515 struct timespec timeoutspec;
1516 struct timespec *ptimeoutspec;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001517
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001518 if (self->kqfd < 0)
1519 return kqueue_queue_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001520
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001521 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1522 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001523
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001524 if (nevents < 0) {
1525 PyErr_Format(PyExc_ValueError,
1526 "Length of eventlist must be 0 or positive, got %d",
1527 nevents);
1528 return NULL;
1529 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001530
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001531 if (otimeout == Py_None || otimeout == NULL) {
1532 ptimeoutspec = NULL;
1533 }
1534 else if (PyNumber_Check(otimeout)) {
1535 double timeout;
1536 long seconds;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001537
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001538 timeout = PyFloat_AsDouble(otimeout);
1539 if (timeout == -1 && PyErr_Occurred())
1540 return NULL;
1541 if (timeout > (double)LONG_MAX) {
1542 PyErr_SetString(PyExc_OverflowError,
1543 "timeout period too long");
1544 return NULL;
1545 }
1546 if (timeout < 0) {
1547 PyErr_SetString(PyExc_ValueError,
1548 "timeout must be positive or None");
1549 return NULL;
1550 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001551
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001552 seconds = (long)timeout;
1553 timeout = timeout - (double)seconds;
1554 timeoutspec.tv_sec = seconds;
1555 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1556 ptimeoutspec = &timeoutspec;
1557 }
1558 else {
1559 PyErr_Format(PyExc_TypeError,
1560 "timeout argument must be an number "
1561 "or None, got %.200s",
1562 Py_TYPE(otimeout)->tp_name);
1563 return NULL;
1564 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001565
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001566 if (ch != NULL && ch != Py_None) {
1567 it = PyObject_GetIter(ch);
1568 if (it == NULL) {
1569 PyErr_SetString(PyExc_TypeError,
1570 "changelist is not iterable");
1571 return NULL;
1572 }
1573 nchanges = PyObject_Size(ch);
1574 if (nchanges < 0) {
1575 goto error;
1576 }
Georg Brandlea370a92010-02-23 21:48:57 +00001577
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001578 chl = PyMem_New(struct kevent, nchanges);
1579 if (chl == NULL) {
1580 PyErr_NoMemory();
1581 goto error;
1582 }
1583 i = 0;
1584 while ((ei = PyIter_Next(it)) != NULL) {
1585 if (!kqueue_event_Check(ei)) {
1586 Py_DECREF(ei);
1587 PyErr_SetString(PyExc_TypeError,
1588 "changelist must be an iterable of "
1589 "select.kevent objects");
1590 goto error;
1591 } else {
1592 chl[i++] = ((kqueue_event_Object *)ei)->e;
1593 }
1594 Py_DECREF(ei);
1595 }
1596 }
1597 Py_CLEAR(it);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001598
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001599 /* event list */
1600 if (nevents) {
1601 evl = PyMem_New(struct kevent, nevents);
1602 if (evl == NULL) {
1603 PyErr_NoMemory();
1604 goto error;
1605 }
1606 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001607
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001608 Py_BEGIN_ALLOW_THREADS
1609 gotevents = kevent(self->kqfd, chl, nchanges,
1610 evl, nevents, ptimeoutspec);
1611 Py_END_ALLOW_THREADS
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001612
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001613 if (gotevents == -1) {
1614 PyErr_SetFromErrno(PyExc_OSError);
1615 goto error;
1616 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001617
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001618 result = PyList_New(gotevents);
1619 if (result == NULL) {
1620 goto error;
1621 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001622
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001623 for (i = 0; i < gotevents; i++) {
1624 kqueue_event_Object *ch;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001625
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001626 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1627 if (ch == NULL) {
1628 goto error;
1629 }
1630 ch->e = evl[i];
1631 PyList_SET_ITEM(result, i, (PyObject *)ch);
1632 }
1633 PyMem_Free(chl);
1634 PyMem_Free(evl);
1635 return result;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001636
1637 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001638 PyMem_Free(chl);
1639 PyMem_Free(evl);
1640 Py_XDECREF(result);
1641 Py_XDECREF(it);
1642 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001643}
1644
1645PyDoc_STRVAR(kqueue_queue_control_doc,
Georg Brandl2f3bd832008-09-21 07:14:44 +00001646"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001647\n\
1648Calls the kernel kevent function.\n\
1649- changelist must be a list of kevent objects describing the changes\n\
1650 to be made to the kernel's watch list or None.\n\
1651- max_events lets you specify the maximum number of events that the\n\
1652 kernel will return.\n\
1653- timeout is the maximum time to wait in seconds, or else None,\n\
1654 to wait forever. timeout accepts floats for smaller timeouts, too.");
1655
1656
1657static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001658 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1659 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1660 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1661 kqueue_queue_close_doc},
1662 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1663 kqueue_queue_fileno_doc},
1664 {"control", (PyCFunction)kqueue_queue_control,
1665 METH_VARARGS , kqueue_queue_control_doc},
1666 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001667};
1668
1669static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001670 {"closed", (getter)kqueue_queue_get_closed, NULL,
1671 "True if the kqueue handler is closed"},
1672 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001673};
1674
1675PyDoc_STRVAR(kqueue_queue_doc,
1676"Kqueue syscall wrapper.\n\
1677\n\
1678For example, to start watching a socket for input:\n\
1679>>> kq = kqueue()\n\
1680>>> sock = socket()\n\
1681>>> sock.connect((host, port))\n\
1682>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1683\n\
1684To wait one second for it to become writeable:\n\
1685>>> kq.control(None, 1, 1000)\n\
1686\n\
1687To stop listening:\n\
1688>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1689
1690static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001691 PyVarObject_HEAD_INIT(NULL, 0)
1692 "select.kqueue", /* tp_name */
1693 sizeof(kqueue_queue_Object), /* tp_basicsize */
1694 0, /* tp_itemsize */
1695 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1696 0, /* tp_print */
1697 0, /* tp_getattr */
1698 0, /* tp_setattr */
1699 0, /* tp_compare */
1700 0, /* tp_repr */
1701 0, /* tp_as_number */
1702 0, /* tp_as_sequence */
1703 0, /* tp_as_mapping */
1704 0, /* tp_hash */
1705 0, /* tp_call */
1706 0, /* tp_str */
1707 0, /* tp_getattro */
1708 0, /* tp_setattro */
1709 0, /* tp_as_buffer */
1710 Py_TPFLAGS_DEFAULT, /* tp_flags */
1711 kqueue_queue_doc, /* tp_doc */
1712 0, /* tp_traverse */
1713 0, /* tp_clear */
1714 0, /* tp_richcompare */
1715 0, /* tp_weaklistoffset */
1716 0, /* tp_iter */
1717 0, /* tp_iternext */
1718 kqueue_queue_methods, /* tp_methods */
1719 0, /* tp_members */
1720 kqueue_queue_getsetlist, /* tp_getset */
1721 0, /* tp_base */
1722 0, /* tp_dict */
1723 0, /* tp_descr_get */
1724 0, /* tp_descr_set */
1725 0, /* tp_dictoffset */
1726 0, /* tp_init */
1727 0, /* tp_alloc */
1728 kqueue_queue_new, /* tp_new */
1729 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001730};
1731
1732#endif /* HAVE_KQUEUE */
1733/* ************************************************************************ */
1734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001736"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1737\n\
1738Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001739The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001740rlist -- wait until ready for reading\n\
1741wlist -- wait until ready for writing\n\
1742xlist -- wait for an ``exceptional condition''\n\
1743If only one kind of condition is required, pass [] for the other lists.\n\
1744A file descriptor is either a socket or file object, or a small integer\n\
1745gotten from a fileno() method call on one of those.\n\
1746\n\
1747The optional 4th argument specifies a timeout in seconds; it may be\n\
1748a floating point number to specify fractions of seconds. If it is absent\n\
1749or None, the call will never time out.\n\
1750\n\
1751The return value is a tuple of three lists corresponding to the first three\n\
1752arguments; each contains the subset of the corresponding file descriptors\n\
1753that are ready.\n\
1754\n\
1755*** IMPORTANT NOTICE ***\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001756On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +00001757descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001758
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001759static PyMethodDef select_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001760 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natalia41cf292013-01-19 12:15:56 +01001761#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001762 {"poll", select_poll, METH_NOARGS, poll_doc},
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001763#endif /* HAVE_POLL */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001764 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001765};
1766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001768"This module supports asynchronous I/O on multiple file descriptors.\n\
1769\n\
1770*** IMPORTANT NOTICE ***\n\
Neal Norwitz2a30cd02006-07-10 01:18:57 +00001771On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001772
Mark Hammond62b1ab12002-07-23 06:31:15 +00001773PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001774initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001775{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001776 PyObject *m;
1777 m = Py_InitModule3("select", select_methods, module_doc);
1778 if (m == NULL)
1779 return;
Fred Drake4baedc12002-04-01 14:53:37 +00001780
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001781 SelectError = PyErr_NewException("select.error", NULL, NULL);
1782 Py_INCREF(SelectError);
1783 PyModule_AddObject(m, "error", SelectError);
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001784
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001785#ifdef PIPE_BUF
R. David Murray1d9d16e2010-10-16 00:43:13 +00001786#ifdef HAVE_BROKEN_PIPE_BUF
1787#undef PIPE_BUF
1788#define PIPE_BUF 512
1789#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001790 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001791#endif
Gregory P. Smith9d36fd22009-07-03 20:48:31 +00001792
Charles-François Natalia41cf292013-01-19 12:15:56 +01001793#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001794#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001795 if (select_have_broken_poll()) {
1796 if (PyObject_DelAttrString(m, "poll") == -1) {
1797 PyErr_Clear();
1798 }
1799 } else {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001800#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001801 {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001802#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001803 Py_TYPE(&poll_Type) = &PyType_Type;
1804 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1805 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1806 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1807 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1808 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1809 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001810
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001811#ifdef POLLRDNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001812 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001813#endif
1814#ifdef POLLRDBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001815 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001816#endif
1817#ifdef POLLWRNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001818 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001819#endif
1820#ifdef POLLWRBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001821 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001822#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001823#ifdef POLLMSG
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001824 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001825#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001826 }
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001827#endif /* HAVE_POLL */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001828
1829#ifdef HAVE_EPOLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001830 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1831 if (PyType_Ready(&pyEpoll_Type) < 0)
1832 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001833
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001834 Py_INCREF(&pyEpoll_Type);
1835 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001836
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001837 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1838 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1839 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1840 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1841 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1842 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001843#ifdef EPOLLONESHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001844 /* Kernel 2.6.2+ */
1845 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001846#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001847 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1848 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1849 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1850 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1851 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1852 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001853#endif /* HAVE_EPOLL */
1854
1855#ifdef HAVE_KQUEUE
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001856 kqueue_event_Type.tp_new = PyType_GenericNew;
1857 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1858 if(PyType_Ready(&kqueue_event_Type) < 0)
1859 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001860
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001861 Py_INCREF(&kqueue_event_Type);
1862 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001863
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001864 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1865 if(PyType_Ready(&kqueue_queue_Type) < 0)
1866 return;
1867 Py_INCREF(&kqueue_queue_Type);
1868 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1869
1870 /* event filters */
1871 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1872 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1873 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1874 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1875 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001876#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001877 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001878#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001879 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1880 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001881
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001882 /* event flags */
1883 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1884 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1885 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1886 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1887 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1888 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001889
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001890 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1891 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001892
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001893 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1894 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001895
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001896 /* READ WRITE filter flag */
1897 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001898
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001899 /* VNODE filter flags */
1900 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1903 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001907
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001908 /* PROC filter flags */
1909 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1910 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001914
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001915 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1916 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1917 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1918
1919 /* NETDEV filter flags */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001920#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001921 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1922 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1923 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001924#endif
1925
1926#endif /* HAVE_KQUEUE */
Guido van Rossumed233a51992-06-23 09:07:03 +00001927}