blob: 6e3e6cbf1d5e4916a172319caa8caac508ba7dd9 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Jesus Cead8b9ae62011-11-14 19:07:41 +010010#ifdef HAVE_SYS_DEVPOLL_H
11#include <sys/resource.h>
12#include <sys/devpoll.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018#ifdef __APPLE__
19 /* Perform runtime testing for a broken poll on OSX to make it easier
20 * to use the same binary on multiple releases of the OS.
21 */
22#undef HAVE_BROKEN_POLL
23#endif
24
Tim Petersd92dfe02000-12-12 01:18:41 +000025/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
26 64 is too small (too many people have bumped into that limit).
27 Here we boost it.
28 Users who want even more than the boosted limit should #define
29 FD_SETSIZE higher before this; e.g., via compiler /D switch.
30*/
31#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
32#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000034
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000035#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000036#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000037#elif defined(HAVE_SYS_POLL_H)
38#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000039#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000040
Guido van Rossum37273171996-12-09 18:47:43 +000041#ifdef __sgi
42/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000043extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000044#endif
45
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000048#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000050#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <sys/time.h>
52#include <utils.h>
53#endif
54
Guido van Rossum6f489d91996-06-28 20:15:15 +000055#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000056# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000057# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000058#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000060# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061# include <socket.h>
62# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000063#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000064
Barry Warsawc1cb3601996-12-12 22:16:21 +000065/* list of Python objects and their file descriptor */
66typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 PyObject *obj; /* owned reference */
68 SOCKET fd;
69 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000070} pylist;
71
Barry Warsawc1cb3601996-12-12 22:16:21 +000072static void
Tim Peters4b046c22001-08-16 21:59:46 +000073reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 int i;
76 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
77 Py_XDECREF(fd2obj[i].obj);
78 fd2obj[i].obj = NULL;
79 }
80 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000081}
82
83
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000084/* returns -1 and sets the Python exception if an error occurred, otherwise
85 returns a number >= 0
86*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000087static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000088seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 int max = -1;
91 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000092 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyObject* fast_seq = NULL;
94 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
97 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000098
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000099 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 if (!fast_seq)
101 return -1;
102
103 len = PySequence_Fast_GET_SIZE(fast_seq);
104
105 for (i = 0; i < len; i++) {
106 SOCKET v;
107
108 /* any intervening fileno() calls could decr this refcnt */
109 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000110 return -1;
111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 Py_INCREF(o);
113 v = PyObject_AsFileDescriptor( o );
114 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000116#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200119 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 PyErr_SetString(PyExc_ValueError,
121 "filedescriptor out of range in select()");
122 goto finally;
123 }
124 if (v > max)
125 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 /* add object and its file descriptor to the list */
130 if (index >= FD_SETSIZE) {
131 PyErr_SetString(PyExc_ValueError,
132 "too many file descriptors in select()");
133 goto finally;
134 }
135 fd2obj[index].obj = o;
136 fd2obj[index].fd = v;
137 fd2obj[index].sentinel = 0;
138 fd2obj[++index].sentinel = -1;
139 }
140 Py_DECREF(fast_seq);
141 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142
143 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 Py_XDECREF(o);
145 Py_DECREF(fast_seq);
146 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000147}
148
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149/* returns NULL and sets the Python exception if an error occurred */
150static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000151set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 int i, j, count=0;
154 PyObject *list, *o;
155 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
158 if (FD_ISSET(fd2obj[j].fd, set))
159 count++;
160 }
161 list = PyList_New(count);
162 if (!list)
163 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 i = 0;
166 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
167 fd = fd2obj[j].fd;
168 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 o = fd2obj[j].obj;
170 fd2obj[j].obj = NULL;
171 /* transfer ownership */
172 if (PyList_SetItem(list, i, o) < 0)
173 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 i++;
176 }
177 }
178 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000179 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 Py_DECREF(list);
181 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000182}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000183
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#undef SELECT_USES_HEAP
185#if FD_SETSIZE > 1024
186#define SELECT_USES_HEAP
187#endif /* FD_SETSIZE > 1024 */
188
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000189static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000190select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000191{
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 /* XXX: All this should probably be implemented as follows:
196 * - find the highest descriptor we're interested in
197 * - add one
198 * - that's the size
199 * See: Stevens, APitUE, $12.5.1
200 */
201 pylist rfd2obj[FD_SETSIZE + 1];
202 pylist wfd2obj[FD_SETSIZE + 1];
203 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000204#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 PyObject *ifdlist, *ofdlist, *efdlist;
206 PyObject *ret = NULL;
207 PyObject *tout = Py_None;
208 fd_set ifdset, ofdset, efdset;
209 double timeout;
210 struct timeval tv, *tvp;
211 long seconds;
212 int imax, omax, emax, max;
213 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 /* convert arguments */
216 if (!PyArg_UnpackTuple(args, "select", 3, 4,
217 &ifdlist, &ofdlist, &efdlist, &tout))
218 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 if (tout == Py_None)
221 tvp = (struct timeval *)0;
222 else if (!PyNumber_Check(tout)) {
223 PyErr_SetString(PyExc_TypeError,
224 "timeout must be a float or None");
225 return NULL;
226 }
227 else {
228 timeout = PyFloat_AsDouble(tout);
229 if (timeout == -1 && PyErr_Occurred())
230 return NULL;
231 if (timeout > (double)LONG_MAX) {
232 PyErr_SetString(PyExc_OverflowError,
233 "timeout period too long");
234 return NULL;
235 }
Antoine Pitrou131a6412011-04-09 23:49:58 +0200236 if (timeout < 0) {
237 PyErr_SetString(PyExc_ValueError,
238 "timeout must be non-negative");
239 return NULL;
240 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 seconds = (long)timeout;
242 timeout = timeout - (double)seconds;
243 tv.tv_sec = seconds;
244 tv.tv_usec = (long)(timeout * 1E6);
245 tvp = &tv;
246 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000247
Guido van Rossumed233a51992-06-23 09:07:03 +0000248
Barry Warsawb44740f2001-08-16 16:52:59 +0000249#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 /* Allocate memory for the lists */
251 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
255 if (rfd2obj) PyMem_DEL(rfd2obj);
256 if (wfd2obj) PyMem_DEL(wfd2obj);
257 if (efd2obj) PyMem_DEL(efd2obj);
258 return PyErr_NoMemory();
259 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000260#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 /* Convert sequences to fd_sets, and get maximum fd number
262 * propagates the Python exception set in seq2set()
263 */
264 rfd2obj[0].sentinel = -1;
265 wfd2obj[0].sentinel = -1;
266 efd2obj[0].sentinel = -1;
267 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
268 goto finally;
269 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
270 goto finally;
271 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
272 goto finally;
273 max = imax;
274 if (omax > max) max = omax;
275 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 Py_BEGIN_ALLOW_THREADS
278 n = select(max, &ifdset, &ofdset, &efdset, tvp);
279 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000280
Thomas Heller106f4c72002-09-24 16:51:00 +0000281#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200283 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000285#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200287 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000289#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 else {
291 /* any of these three calls can raise an exception. it's more
292 convenient to test for this after all three calls... but
293 is that acceptable?
294 */
295 ifdlist = set2list(&ifdset, rfd2obj);
296 ofdlist = set2list(&ofdset, wfd2obj);
297 efdlist = set2list(&efdset, efd2obj);
298 if (PyErr_Occurred())
299 ret = NULL;
300 else
301 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 Py_DECREF(ifdlist);
304 Py_DECREF(ofdlist);
305 Py_DECREF(efdlist);
306 }
307
Barry Warsawc1cb3601996-12-12 22:16:21 +0000308 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 reap_obj(rfd2obj);
310 reap_obj(wfd2obj);
311 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000312#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyMem_DEL(rfd2obj);
314 PyMem_DEL(wfd2obj);
315 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000316#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000318}
319
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000320#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000322 * poll() support
323 */
324
325typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 PyObject_HEAD
327 PyObject *dict;
328 int ufd_uptodate;
329 int ufd_len;
330 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331} pollObject;
332
Jeremy Hylton938ace62002-07-17 16:30:39 +0000333static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000336 contained within a pollObject. Return 1 on success, 0 on an error.
337*/
338
339static int
340update_ufd_array(pollObject *self)
341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 Py_ssize_t i, pos;
343 PyObject *key, *value;
344 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 self->ufd_len = PyDict_Size(self->dict);
347 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
348 if (self->ufds == NULL) {
349 self->ufds = old_ufds;
350 PyErr_NoMemory();
351 return 0;
352 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 i = pos = 0;
355 while (PyDict_Next(self->dict, &pos, &key, &value)) {
356 self->ufds[i].fd = PyLong_AsLong(key);
357 self->ufds[i].events = (short)PyLong_AsLong(value);
358 i++;
359 }
360 self->ufd_uptodate = 1;
361 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362}
363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000364PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000365"register(fd [, eventmask] ) -> None\n\n\
366Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000367fd -- either an integer, or an object with a fileno() method returning an\n\
368 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000369events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370
371static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 PyObject *o, *key, *value;
375 int fd, events = POLLIN | POLLPRI | POLLOUT;
376 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
379 return NULL;
380 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 fd = PyObject_AsFileDescriptor(o);
383 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 /* Add entry to the internal dictionary: the key is the
386 file descriptor, and the value is the event mask. */
387 key = PyLong_FromLong(fd);
388 if (key == NULL)
389 return NULL;
390 value = PyLong_FromLong(events);
391 if (value == NULL) {
392 Py_DECREF(key);
393 return NULL;
394 }
395 err = PyDict_SetItem(self->dict, key, value);
396 Py_DECREF(key);
397 Py_DECREF(value);
398 if (err < 0)
399 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 self->ufd_uptodate = 0;
402
403 Py_INCREF(Py_None);
404 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000405}
406
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000407PyDoc_STRVAR(poll_modify_doc,
408"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000409Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000410fd -- either an integer, or an object with a fileno() method returning an\n\
411 int.\n\
412events -- an optional bitmask describing the type of events to check for");
413
414static PyObject *
415poll_modify(pollObject *self, PyObject *args)
416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyObject *o, *key, *value;
418 int fd, events;
419 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
422 return NULL;
423 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 fd = PyObject_AsFileDescriptor(o);
426 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 /* Modify registered fd */
429 key = PyLong_FromLong(fd);
430 if (key == NULL)
431 return NULL;
432 if (PyDict_GetItem(self->dict, key) == NULL) {
433 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200434 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 return NULL;
436 }
437 value = PyLong_FromLong(events);
438 if (value == NULL) {
439 Py_DECREF(key);
440 return NULL;
441 }
442 err = PyDict_SetItem(self->dict, key, value);
443 Py_DECREF(key);
444 Py_DECREF(value);
445 if (err < 0)
446 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 self->ufd_uptodate = 0;
449
450 Py_INCREF(Py_None);
451 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000452}
453
454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000455PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000457Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458
459static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 PyObject *key;
463 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 fd = PyObject_AsFileDescriptor( o );
466 if (fd == -1)
467 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 /* Check whether the fd is already in the array */
470 key = PyLong_FromLong(fd);
471 if (key == NULL)
472 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (PyDict_DelItem(self->dict, key) == -1) {
475 Py_DECREF(key);
476 /* This will simply raise the KeyError set by PyDict_DelItem
477 if the file descriptor isn't registered. */
478 return NULL;
479 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 Py_DECREF(key);
482 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 Py_INCREF(Py_None);
485 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486}
487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
490Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000491any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
493static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 PyObject *result_list = NULL, *tout = NULL;
497 int timeout = 0, poll_result, i, j;
498 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
501 return NULL;
502 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 /* Check values for timeout */
505 if (tout == NULL || tout == Py_None)
506 timeout = -1;
507 else if (!PyNumber_Check(tout)) {
508 PyErr_SetString(PyExc_TypeError,
509 "timeout must be an integer or None");
510 return NULL;
511 }
512 else {
513 tout = PyNumber_Long(tout);
514 if (!tout)
515 return NULL;
516 timeout = PyLong_AsLong(tout);
517 Py_DECREF(tout);
518 if (timeout == -1 && PyErr_Occurred())
519 return NULL;
520 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 /* Ensure the ufd array is up to date */
523 if (!self->ufd_uptodate)
524 if (update_ufd_array(self) == 0)
525 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 /* call poll() */
528 Py_BEGIN_ALLOW_THREADS
529 poll_result = poll(self->ufds, self->ufd_len, timeout);
530 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200533 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 return NULL;
535 }
536
537 /* build the result list */
538
539 result_list = PyList_New(poll_result);
540 if (!result_list)
541 return NULL;
542 else {
543 for (i = 0, j = 0; j < poll_result; j++) {
544 /* skip to the next fired descriptor */
545 while (!self->ufds[i].revents) {
546 i++;
547 }
548 /* if we hit a NULL return, set value to NULL
549 and break out of loop; code at end will
550 clean up result_list */
551 value = PyTuple_New(2);
552 if (value == NULL)
553 goto error;
554 num = PyLong_FromLong(self->ufds[i].fd);
555 if (num == NULL) {
556 Py_DECREF(value);
557 goto error;
558 }
559 PyTuple_SET_ITEM(value, 0, num);
560
561 /* The &0xffff is a workaround for AIX. 'revents'
562 is a 16-bit short, and IBM assigned POLLNVAL
563 to be 0x8000, so the conversion to int results
564 in a negative number. See SF bug #923315. */
565 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
566 if (num == NULL) {
567 Py_DECREF(value);
568 goto error;
569 }
570 PyTuple_SET_ITEM(value, 1, num);
571 if ((PyList_SetItem(result_list, j, value)) == -1) {
572 Py_DECREF(value);
573 goto error;
574 }
575 i++;
576 }
577 }
578 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000579
580 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 Py_DECREF(result_list);
582 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583}
584
585static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 {"register", (PyCFunction)poll_register,
587 METH_VARARGS, poll_register_doc},
588 {"modify", (PyCFunction)poll_modify,
589 METH_VARARGS, poll_modify_doc},
590 {"unregister", (PyCFunction)poll_unregister,
591 METH_O, poll_unregister_doc},
592 {"poll", (PyCFunction)poll_poll,
593 METH_VARARGS, poll_poll_doc},
594 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000595};
596
597static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000598newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 pollObject *self;
601 self = PyObject_New(pollObject, &poll_Type);
602 if (self == NULL)
603 return NULL;
604 /* ufd_uptodate is a Boolean, denoting whether the
605 array pointed to by ufds matches the contents of the dictionary. */
606 self->ufd_uptodate = 0;
607 self->ufds = NULL;
608 self->dict = PyDict_New();
609 if (self->dict == NULL) {
610 Py_DECREF(self);
611 return NULL;
612 }
613 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000614}
615
616static void
617poll_dealloc(pollObject *self)
618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 if (self->ufds != NULL)
620 PyMem_DEL(self->ufds);
621 Py_XDECREF(self->dict);
622 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623}
624
Tim Peters0c322792002-07-17 16:49:03 +0000625static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 0, /*tp_getattr*/
636 0, /*tp_setattr*/
637 0, /*tp_reserved*/
638 0, /*tp_repr*/
639 0, /*tp_as_number*/
640 0, /*tp_as_sequence*/
641 0, /*tp_as_mapping*/
642 0, /*tp_hash*/
643 0, /*tp_call*/
644 0, /*tp_str*/
645 0, /*tp_getattro*/
646 0, /*tp_setattro*/
647 0, /*tp_as_buffer*/
648 Py_TPFLAGS_DEFAULT, /*tp_flags*/
649 0, /*tp_doc*/
650 0, /*tp_traverse*/
651 0, /*tp_clear*/
652 0, /*tp_richcompare*/
653 0, /*tp_weaklistoffset*/
654 0, /*tp_iter*/
655 0, /*tp_iternext*/
656 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657};
658
Jesus Cead8b9ae62011-11-14 19:07:41 +0100659#ifdef HAVE_SYS_DEVPOLL_H
660typedef struct {
661 PyObject_HEAD
662 int fd_devpoll;
663 int max_n_fds;
664 int n_fds;
665 struct pollfd *fds;
666} devpollObject;
667
668static PyTypeObject devpoll_Type;
669
670static int devpoll_flush(devpollObject *self)
671{
672 int size, n;
673
674 if (!self->n_fds) return 0;
675
676 size = sizeof(struct pollfd)*self->n_fds;
677 self->n_fds = 0;
678
679 Py_BEGIN_ALLOW_THREADS
680 n = write(self->fd_devpoll, self->fds, size);
681 Py_END_ALLOW_THREADS
682
683 if (n == -1 ) {
684 PyErr_SetFromErrno(PyExc_IOError);
685 return -1;
686 }
687 if (n < size) {
688 /*
689 ** Data writed to /dev/poll is a binary data structure. It is not
690 ** clear what to do if a partial write occurred. For now, raise
691 ** an exception and see if we actually found this problem in
692 ** the wild.
693 ** See http://bugs.python.org/issue6397.
694 */
695 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
696 "Please, report at http://bugs.python.org/. "
697 "Data to report: Size tried: %d, actual size written: %d.",
698 size, n);
699 return -1;
700 }
701 return 0;
702}
703
704static PyObject *
705internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
706{
707 PyObject *o;
708 int fd, events = POLLIN | POLLPRI | POLLOUT;
709
710 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
711 return NULL;
712 }
713
714 fd = PyObject_AsFileDescriptor(o);
715 if (fd == -1) return NULL;
716
717 if (remove) {
718 self->fds[self->n_fds].fd = fd;
719 self->fds[self->n_fds].events = POLLREMOVE;
720
721 if (++self->n_fds == self->max_n_fds) {
722 if (devpoll_flush(self))
723 return NULL;
724 }
725 }
726
727 self->fds[self->n_fds].fd = fd;
728 self->fds[self->n_fds].events = events;
729
730 if (++self->n_fds == self->max_n_fds) {
731 if (devpoll_flush(self))
732 return NULL;
733 }
734
735 Py_RETURN_NONE;
736}
737
738PyDoc_STRVAR(devpoll_register_doc,
739"register(fd [, eventmask] ) -> None\n\n\
740Register a file descriptor with the polling object.\n\
741fd -- either an integer, or an object with a fileno() method returning an\n\
742 int.\n\
743events -- an optional bitmask describing the type of events to check for");
744
745static PyObject *
746devpoll_register(devpollObject *self, PyObject *args)
747{
748 return internal_devpoll_register(self, args, 0);
749}
750
751PyDoc_STRVAR(devpoll_modify_doc,
752"modify(fd[, eventmask]) -> None\n\n\
753Modify a possible already registered file descriptor.\n\
754fd -- either an integer, or an object with a fileno() method returning an\n\
755 int.\n\
756events -- an optional bitmask describing the type of events to check for");
757
758static PyObject *
759devpoll_modify(devpollObject *self, PyObject *args)
760{
761 return internal_devpoll_register(self, args, 1);
762}
763
764
765PyDoc_STRVAR(devpoll_unregister_doc,
766"unregister(fd) -> None\n\n\
767Remove a file descriptor being tracked by the polling object.");
768
769static PyObject *
770devpoll_unregister(devpollObject *self, PyObject *o)
771{
772 int fd;
773
774 fd = PyObject_AsFileDescriptor( o );
775 if (fd == -1)
776 return NULL;
777
778 self->fds[self->n_fds].fd = fd;
779 self->fds[self->n_fds].events = POLLREMOVE;
780
781 if (++self->n_fds == self->max_n_fds) {
782 if (devpoll_flush(self))
783 return NULL;
784 }
785
786 Py_RETURN_NONE;
787}
788
789PyDoc_STRVAR(devpoll_poll_doc,
790"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
791Polls the set of registered file descriptors, returning a list containing \n\
792any descriptors that have events or errors to report.");
793
794static PyObject *
795devpoll_poll(devpollObject *self, PyObject *args)
796{
797 struct dvpoll dvp;
798 PyObject *result_list = NULL, *tout = NULL;
799 int poll_result, i;
800 long timeout;
801 PyObject *value, *num1, *num2;
802
803 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
804 return NULL;
805 }
806
807 /* Check values for timeout */
808 if (tout == NULL || tout == Py_None)
809 timeout = -1;
810 else if (!PyNumber_Check(tout)) {
811 PyErr_SetString(PyExc_TypeError,
812 "timeout must be an integer or None");
813 return NULL;
814 }
815 else {
816 tout = PyNumber_Long(tout);
817 if (!tout)
818 return NULL;
819 timeout = PyLong_AsLong(tout);
820 Py_DECREF(tout);
821 if (timeout == -1 && PyErr_Occurred())
822 return NULL;
823 }
824
825 if ((timeout < -1) || (timeout > INT_MAX)) {
826 PyErr_SetString(PyExc_OverflowError,
827 "timeout is out of range");
828 return NULL;
829 }
830
831 if (devpoll_flush(self))
832 return NULL;
833
834 dvp.dp_fds = self->fds;
835 dvp.dp_nfds = self->max_n_fds;
836 dvp.dp_timeout = timeout;
837
838 /* call devpoll() */
839 Py_BEGIN_ALLOW_THREADS
840 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
841 Py_END_ALLOW_THREADS
842
843 if (poll_result < 0) {
844 PyErr_SetFromErrno(PyExc_IOError);
845 return NULL;
846 }
847
848 /* build the result list */
849
850 result_list = PyList_New(poll_result);
851 if (!result_list)
852 return NULL;
853 else {
854 for (i = 0; i < poll_result; i++) {
855 num1 = PyLong_FromLong(self->fds[i].fd);
856 num2 = PyLong_FromLong(self->fds[i].revents);
857 if ((num1 == NULL) || (num2 == NULL)) {
858 Py_XDECREF(num1);
859 Py_XDECREF(num2);
860 goto error;
861 }
862 value = PyTuple_Pack(2, num1, num2);
863 Py_DECREF(num1);
864 Py_DECREF(num2);
865 if (value == NULL)
866 goto error;
867 if ((PyList_SetItem(result_list, i, value)) == -1) {
868 Py_DECREF(value);
869 goto error;
870 }
871 }
872 }
873
874 return result_list;
875
876 error:
877 Py_DECREF(result_list);
878 return NULL;
879}
880
881static PyMethodDef devpoll_methods[] = {
882 {"register", (PyCFunction)devpoll_register,
883 METH_VARARGS, devpoll_register_doc},
884 {"modify", (PyCFunction)devpoll_modify,
885 METH_VARARGS, devpoll_modify_doc},
886 {"unregister", (PyCFunction)devpoll_unregister,
887 METH_O, devpoll_unregister_doc},
888 {"poll", (PyCFunction)devpoll_poll,
889 METH_VARARGS, devpoll_poll_doc},
890 {NULL, NULL} /* sentinel */
891};
892
893static devpollObject *
894newDevPollObject(void)
895{
896 devpollObject *self;
897 int fd_devpoll, limit_result;
898 struct pollfd *fds;
899 struct rlimit limit;
900
901 Py_BEGIN_ALLOW_THREADS
902 /*
903 ** If we try to process more that getrlimit()
904 ** fds, the kernel will give an error, so
905 ** we set the limit here. It is a dynamic
906 ** value, because we can change rlimit() anytime.
907 */
908 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
909 if (limit_result != -1)
910 fd_devpoll = open("/dev/poll", O_RDWR);
911 Py_END_ALLOW_THREADS
912
913 if (limit_result == -1) {
914 PyErr_SetFromErrno(PyExc_OSError);
915 return NULL;
916 }
917 if (fd_devpoll == -1) {
918 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
919 return NULL;
920 }
921
922 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
923 if (fds == NULL) {
924 close(fd_devpoll);
925 PyErr_NoMemory();
926 return NULL;
927 }
928
929 self = PyObject_New(devpollObject, &devpoll_Type);
930 if (self == NULL) {
931 close(fd_devpoll);
932 PyMem_DEL(fds);
933 return NULL;
934 }
935 self->fd_devpoll = fd_devpoll;
936 self->max_n_fds = limit.rlim_cur;
937 self->n_fds = 0;
938 self->fds = fds;
939
940 return self;
941}
942
943static void
944devpoll_dealloc(devpollObject *self)
945{
946 Py_BEGIN_ALLOW_THREADS
947 close(self->fd_devpoll);
948 Py_END_ALLOW_THREADS
949
950 PyMem_DEL(self->fds);
951
952 PyObject_Del(self);
953}
954
955static PyTypeObject devpoll_Type = {
956 /* The ob_type field must be initialized in the module init function
957 * to be portable to Windows without using C++. */
958 PyVarObject_HEAD_INIT(NULL, 0)
959 "select.devpoll", /*tp_name*/
960 sizeof(devpollObject), /*tp_basicsize*/
961 0, /*tp_itemsize*/
962 /* methods */
963 (destructor)devpoll_dealloc, /*tp_dealloc*/
964 0, /*tp_print*/
965 0, /*tp_getattr*/
966 0, /*tp_setattr*/
967 0, /*tp_reserved*/
968 0, /*tp_repr*/
969 0, /*tp_as_number*/
970 0, /*tp_as_sequence*/
971 0, /*tp_as_mapping*/
972 0, /*tp_hash*/
973 0, /*tp_call*/
974 0, /*tp_str*/
975 0, /*tp_getattro*/
976 0, /*tp_setattro*/
977 0, /*tp_as_buffer*/
978 Py_TPFLAGS_DEFAULT, /*tp_flags*/
979 0, /*tp_doc*/
980 0, /*tp_traverse*/
981 0, /*tp_clear*/
982 0, /*tp_richcompare*/
983 0, /*tp_weaklistoffset*/
984 0, /*tp_iter*/
985 0, /*tp_iternext*/
986 devpoll_methods, /*tp_methods*/
987};
988#endif /* HAVE_SYS_DEVPOLL_H */
989
990
991
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000992PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000993"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000994unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000995
996static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000997select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001000}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001
Jesus Cead8b9ae62011-11-14 19:07:41 +01001002#ifdef HAVE_SYS_DEVPOLL_H
1003PyDoc_STRVAR(devpoll_doc,
1004"Returns a polling object, which supports registering and\n\
1005unregistering file descriptors, and then polling them for I/O events.");
1006
1007static PyObject *
1008select_devpoll(PyObject *self, PyObject *unused)
1009{
1010 return (PyObject *)newDevPollObject();
1011}
1012#endif
1013
1014
Thomas Wouters477c8d52006-05-27 19:21:47 +00001015#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001017 * On some systems poll() sets errno on invalid file descriptors. We test
1018 * for this at runtime because this bug may be fixed or introduced between
1019 * OS releases.
1020 */
1021static int select_have_broken_poll(void)
1022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 int poll_test;
1024 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 /* Create a file descriptor to make invalid */
1029 if (pipe(filedes) < 0) {
1030 return 1;
1031 }
1032 poll_struct.fd = filedes[0];
1033 close(filedes[0]);
1034 close(filedes[1]);
1035 poll_test = poll(&poll_struct, 1, 0);
1036 if (poll_test < 0) {
1037 return 1;
1038 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1039 return 1;
1040 }
1041 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042}
1043#endif /* __APPLE__ */
1044
1045#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001046
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001047#ifdef HAVE_EPOLL
1048/* **************************************************************************
1049 * epoll interface for Linux 2.6
1050 *
1051 * Written by Christian Heimes
1052 * Inspired by Twisted's _epoll.pyx and select.poll()
1053 */
1054
1055#ifdef HAVE_SYS_EPOLL_H
1056#include <sys/epoll.h>
1057#endif
1058
1059typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyObject_HEAD
1061 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001062} pyEpoll_Object;
1063
1064static PyTypeObject pyEpoll_Type;
1065#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1066
1067static PyObject *
1068pyepoll_err_closed(void)
1069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
1071 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001072}
1073
1074static int
1075pyepoll_internal_close(pyEpoll_Object *self)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 int save_errno = 0;
1078 if (self->epfd >= 0) {
1079 int epfd = self->epfd;
1080 self->epfd = -1;
1081 Py_BEGIN_ALLOW_THREADS
1082 if (close(epfd) < 0)
1083 save_errno = errno;
1084 Py_END_ALLOW_THREADS
1085 }
1086 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001087}
1088
1089static PyObject *
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001090newPyEpoll_Object(PyTypeObject *type, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001091{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 assert(type != NULL && type->tp_alloc != NULL);
1095 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1096 if (self == NULL)
1097 return NULL;
1098
1099 if (fd == -1) {
1100 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001101 self->epfd = epoll_create1(flags);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 Py_END_ALLOW_THREADS
1103 }
1104 else {
1105 self->epfd = fd;
1106 }
1107 if (self->epfd < 0) {
1108 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001109 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 return NULL;
1111 }
1112 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001113}
1114
1115
1116static PyObject *
1117pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1118{
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001119 int flags = 0, sizehint = 0;
1120 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001121
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001122 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1123 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001125 if (sizehint < 0) {
1126 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1127 return NULL;
1128 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001129
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001130 return newPyEpoll_Object(type, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001131}
1132
1133
1134static void
1135pyepoll_dealloc(pyEpoll_Object *self)
1136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 (void)pyepoll_internal_close(self);
1138 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001139}
1140
1141static PyObject*
1142pyepoll_close(pyEpoll_Object *self)
1143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 errno = pyepoll_internal_close(self);
1145 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001146 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 return NULL;
1148 }
1149 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001150}
1151
1152PyDoc_STRVAR(pyepoll_close_doc,
1153"close() -> None\n\
1154\n\
1155Close the epoll control file descriptor. Further operations on the epoll\n\
1156object will raise an exception.");
1157
1158static PyObject*
1159pyepoll_get_closed(pyEpoll_Object *self)
1160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 if (self->epfd < 0)
1162 Py_RETURN_TRUE;
1163 else
1164 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001165}
1166
1167static PyObject*
1168pyepoll_fileno(pyEpoll_Object *self)
1169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 if (self->epfd < 0)
1171 return pyepoll_err_closed();
1172 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001173}
1174
1175PyDoc_STRVAR(pyepoll_fileno_doc,
1176"fileno() -> int\n\
1177\n\
1178Return the epoll control file descriptor.");
1179
1180static PyObject*
1181pyepoll_fromfd(PyObject *cls, PyObject *args)
1182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1186 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001187
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001188 return newPyEpoll_Object((PyTypeObject*)cls, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001189}
1190
1191PyDoc_STRVAR(pyepoll_fromfd_doc,
1192"fromfd(fd) -> epoll\n\
1193\n\
1194Create an epoll object from a given control fd.");
1195
1196static PyObject *
1197pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 struct epoll_event ev;
1200 int result;
1201 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 if (epfd < 0)
1204 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 fd = PyObject_AsFileDescriptor(pfd);
1207 if (fd == -1) {
1208 return NULL;
1209 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 switch(op) {
1212 case EPOLL_CTL_ADD:
1213 case EPOLL_CTL_MOD:
1214 ev.events = events;
1215 ev.data.fd = fd;
1216 Py_BEGIN_ALLOW_THREADS
1217 result = epoll_ctl(epfd, op, fd, &ev);
1218 Py_END_ALLOW_THREADS
1219 break;
1220 case EPOLL_CTL_DEL:
1221 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1222 * operation required a non-NULL pointer in event, even
1223 * though this argument is ignored. */
1224 Py_BEGIN_ALLOW_THREADS
1225 result = epoll_ctl(epfd, op, fd, &ev);
1226 if (errno == EBADF) {
1227 /* fd already closed */
1228 result = 0;
1229 errno = 0;
1230 }
1231 Py_END_ALLOW_THREADS
1232 break;
1233 default:
1234 result = -1;
1235 errno = EINVAL;
1236 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001239 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 return NULL;
1241 }
1242 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001243}
1244
1245static PyObject *
1246pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 PyObject *pfd;
1249 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1250 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1253 &pfd, &events)) {
1254 return NULL;
1255 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258}
1259
1260PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001261"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001263Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001264fd is the target file descriptor of the operation.\n\
1265events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001266is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1267\n\
1268The epoll interface supports all file descriptors that support poll.");
1269
1270static PyObject *
1271pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1272{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 PyObject *pfd;
1274 unsigned int events;
1275 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1278 &pfd, &events)) {
1279 return NULL;
1280 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001283}
1284
1285PyDoc_STRVAR(pyepoll_modify_doc,
1286"modify(fd, eventmask) -> None\n\
1287\n\
1288fd is the target file descriptor of the operation\n\
1289events is a bit set composed of the various EPOLL constants");
1290
1291static PyObject *
1292pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 PyObject *pfd;
1295 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1298 &pfd)) {
1299 return NULL;
1300 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001303}
1304
1305PyDoc_STRVAR(pyepoll_unregister_doc,
1306"unregister(fd) -> None\n\
1307\n\
1308fd is the target file descriptor of the operation.");
1309
1310static PyObject *
1311pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 double dtimeout = -1.;
1314 int timeout;
1315 int maxevents = -1;
1316 int nfds, i;
1317 PyObject *elist = NULL, *etuple = NULL;
1318 struct epoll_event *evs = NULL;
1319 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 if (self->epfd < 0)
1322 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1325 &dtimeout, &maxevents)) {
1326 return NULL;
1327 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 if (dtimeout < 0) {
1330 timeout = -1;
1331 }
1332 else if (dtimeout * 1000.0 > INT_MAX) {
1333 PyErr_SetString(PyExc_OverflowError,
1334 "timeout is too large");
1335 return NULL;
1336 }
1337 else {
1338 timeout = (int)(dtimeout * 1000.0);
1339 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 if (maxevents == -1) {
1342 maxevents = FD_SETSIZE-1;
1343 }
1344 else if (maxevents < 1) {
1345 PyErr_Format(PyExc_ValueError,
1346 "maxevents must be greater than 0, got %d",
1347 maxevents);
1348 return NULL;
1349 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 evs = PyMem_New(struct epoll_event, maxevents);
1352 if (evs == NULL) {
1353 Py_DECREF(self);
1354 PyErr_NoMemory();
1355 return NULL;
1356 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 Py_BEGIN_ALLOW_THREADS
1359 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1360 Py_END_ALLOW_THREADS
1361 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001362 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 goto error;
1364 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 elist = PyList_New(nfds);
1367 if (elist == NULL) {
1368 goto error;
1369 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 for (i = 0; i < nfds; i++) {
1372 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1373 if (etuple == NULL) {
1374 Py_CLEAR(elist);
1375 goto error;
1376 }
1377 PyList_SET_ITEM(elist, i, etuple);
1378 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379
Christian Heimesf6cd9672008-03-26 13:45:42 +00001380 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyMem_Free(evs);
1382 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383}
1384
1385PyDoc_STRVAR(pyepoll_poll_doc,
1386"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1387\n\
1388Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1389in seconds (as float). -1 makes poll wait indefinitely.\n\
1390Up to maxevents are returned to the caller.");
1391
1392static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 {"fromfd", (PyCFunction)pyepoll_fromfd,
1394 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1395 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1396 pyepoll_close_doc},
1397 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1398 pyepoll_fileno_doc},
1399 {"modify", (PyCFunction)pyepoll_modify,
1400 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1401 {"register", (PyCFunction)pyepoll_register,
1402 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1403 {"unregister", (PyCFunction)pyepoll_unregister,
1404 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1405 {"poll", (PyCFunction)pyepoll_poll,
1406 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1407 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001408};
1409
1410static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 {"closed", (getter)pyepoll_get_closed, NULL,
1412 "True if the epoll handler is closed"},
1413 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001414};
1415
1416PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001417"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418\n\
1419Returns an epolling object\n\
1420\n\
1421sizehint must be a positive integer or -1 for the default size. The\n\
1422sizehint is used to optimize internal data structures. It doesn't limit\n\
1423the maximum number of monitored events.");
1424
1425static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyVarObject_HEAD_INIT(NULL, 0)
1427 "select.epoll", /* tp_name */
1428 sizeof(pyEpoll_Object), /* tp_basicsize */
1429 0, /* tp_itemsize */
1430 (destructor)pyepoll_dealloc, /* tp_dealloc */
1431 0, /* tp_print */
1432 0, /* tp_getattr */
1433 0, /* tp_setattr */
1434 0, /* tp_reserved */
1435 0, /* tp_repr */
1436 0, /* tp_as_number */
1437 0, /* tp_as_sequence */
1438 0, /* tp_as_mapping */
1439 0, /* tp_hash */
1440 0, /* tp_call */
1441 0, /* tp_str */
1442 PyObject_GenericGetAttr, /* tp_getattro */
1443 0, /* tp_setattro */
1444 0, /* tp_as_buffer */
1445 Py_TPFLAGS_DEFAULT, /* tp_flags */
1446 pyepoll_doc, /* tp_doc */
1447 0, /* tp_traverse */
1448 0, /* tp_clear */
1449 0, /* tp_richcompare */
1450 0, /* tp_weaklistoffset */
1451 0, /* tp_iter */
1452 0, /* tp_iternext */
1453 pyepoll_methods, /* tp_methods */
1454 0, /* tp_members */
1455 pyepoll_getsetlist, /* tp_getset */
1456 0, /* tp_base */
1457 0, /* tp_dict */
1458 0, /* tp_descr_get */
1459 0, /* tp_descr_set */
1460 0, /* tp_dictoffset */
1461 0, /* tp_init */
1462 0, /* tp_alloc */
1463 pyepoll_new, /* tp_new */
1464 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001465};
1466
1467#endif /* HAVE_EPOLL */
1468
1469#ifdef HAVE_KQUEUE
1470/* **************************************************************************
1471 * kqueue interface for BSD
1472 *
1473 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1474 * All rights reserved.
1475 *
1476 * Redistribution and use in source and binary forms, with or without
1477 * modification, are permitted provided that the following conditions
1478 * are met:
1479 * 1. Redistributions of source code must retain the above copyright
1480 * notice, this list of conditions and the following disclaimer.
1481 * 2. Redistributions in binary form must reproduce the above copyright
1482 * notice, this list of conditions and the following disclaimer in the
1483 * documentation and/or other materials provided with the distribution.
1484 *
1485 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1486 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1487 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1488 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1489 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1490 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1491 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1492 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1493 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1494 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1495 * SUCH DAMAGE.
1496 */
1497
1498#ifdef HAVE_SYS_EVENT_H
1499#include <sys/event.h>
1500#endif
1501
1502PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001503"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001504\n\
1505This object is the equivalent of the struct kevent for the C API.\n\
1506\n\
1507See the kqueue manpage for more detailed information about the meaning\n\
1508of the arguments.\n\
1509\n\
1510One minor note: while you might hope that udata could store a\n\
1511reference to a python object, it cannot, because it is impossible to\n\
1512keep a proper reference count of the object once it's passed into the\n\
1513kernel. Therefore, I have restricted it to only storing an integer. I\n\
1514recommend ignoring it and simply using the 'ident' field to key off\n\
1515of. You could also set up a dictionary on the python side to store a\n\
1516udata->object mapping.");
1517
1518typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 PyObject_HEAD
1520 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001521} kqueue_event_Object;
1522
1523static PyTypeObject kqueue_event_Type;
1524
1525#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1526
1527typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 PyObject_HEAD
1529 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001530} kqueue_queue_Object;
1531
1532static PyTypeObject kqueue_queue_Type;
1533
1534#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1535
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001536#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1537# error uintptr_t does not match void *!
1538#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1539# define T_UINTPTRT T_ULONGLONG
1540# define T_INTPTRT T_LONGLONG
1541# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1542# define UINTPTRT_FMT_UNIT "K"
1543# define INTPTRT_FMT_UNIT "L"
1544#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1545# define T_UINTPTRT T_ULONG
1546# define T_INTPTRT T_LONG
1547# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1548# define UINTPTRT_FMT_UNIT "k"
1549# define INTPTRT_FMT_UNIT "l"
1550#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1551# define T_UINTPTRT T_UINT
1552# define T_INTPTRT T_INT
1553# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1554# define UINTPTRT_FMT_UNIT "I"
1555# define INTPTRT_FMT_UNIT "i"
1556#else
1557# error uintptr_t does not match int, long, or long long!
1558#endif
1559
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001560/* Unfortunately, we can't store python objects in udata, because
1561 * kevents in the kernel can be removed without warning, which would
1562 * forever lose the refcount on the object stored with it.
1563 */
1564
1565#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1566static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1568 {"filter", T_SHORT, KQ_OFF(e.filter)},
1569 {"flags", T_USHORT, KQ_OFF(e.flags)},
1570 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1571 {"data", T_INTPTRT, KQ_OFF(e.data)},
1572 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1573 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001574};
1575#undef KQ_OFF
1576
1577static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001578
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001579kqueue_event_repr(kqueue_event_Object *s)
1580{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 char buf[1024];
1582 PyOS_snprintf(
1583 buf, sizeof(buf),
1584 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1585 "data=0x%zd udata=%p>",
1586 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1587 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1588 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589}
1590
1591static int
1592kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 PyObject *pfd;
1595 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1596 "data", "udata", NULL};
1597 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1602 &pfd, &(self->e.filter), &(self->e.flags),
1603 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1604 return -1;
1605 }
1606
1607 if (PyLong_Check(pfd)) {
1608 self->e.ident = PyLong_AsUintptr_t(pfd);
1609 }
1610 else {
1611 self->e.ident = PyObject_AsFileDescriptor(pfd);
1612 }
1613 if (PyErr_Occurred()) {
1614 return -1;
1615 }
1616 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001617}
1618
1619static PyObject *
1620kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 if (!kqueue_event_Check(o)) {
1626 if (op == Py_EQ || op == Py_NE) {
1627 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1628 Py_INCREF(res);
1629 return res;
1630 }
1631 PyErr_Format(PyExc_TypeError,
1632 "can't compare %.200s to %.200s",
1633 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1634 return NULL;
1635 }
1636 if (((result = s->e.ident - o->e.ident) == 0) &&
1637 ((result = s->e.filter - o->e.filter) == 0) &&
1638 ((result = s->e.flags - o->e.flags) == 0) &&
1639 ((result = s->e.fflags - o->e.fflags) == 0) &&
1640 ((result = s->e.data - o->e.data) == 0) &&
1641 ((result = s->e.udata - o->e.udata) == 0)
1642 ) {
1643 result = 0;
1644 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 switch (op) {
1647 case Py_EQ:
1648 result = (result == 0);
1649 break;
1650 case Py_NE:
1651 result = (result != 0);
1652 break;
1653 case Py_LE:
1654 result = (result <= 0);
1655 break;
1656 case Py_GE:
1657 result = (result >= 0);
1658 break;
1659 case Py_LT:
1660 result = (result < 0);
1661 break;
1662 case Py_GT:
1663 result = (result > 0);
1664 break;
1665 }
1666 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001667}
1668
1669static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 PyVarObject_HEAD_INIT(NULL, 0)
1671 "select.kevent", /* tp_name */
1672 sizeof(kqueue_event_Object), /* tp_basicsize */
1673 0, /* tp_itemsize */
1674 0, /* tp_dealloc */
1675 0, /* tp_print */
1676 0, /* tp_getattr */
1677 0, /* tp_setattr */
1678 0, /* tp_reserved */
1679 (reprfunc)kqueue_event_repr, /* 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_event_doc, /* tp_doc */
1691 0, /* tp_traverse */
1692 0, /* tp_clear */
1693 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1694 0, /* tp_weaklistoffset */
1695 0, /* tp_iter */
1696 0, /* tp_iternext */
1697 0, /* tp_methods */
1698 kqueue_event_members, /* tp_members */
1699 0, /* 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 (initproc)kqueue_event_init, /* tp_init */
1706 0, /* tp_alloc */
1707 0, /* tp_new */
1708 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001709};
1710
1711static PyObject *
1712kqueue_queue_err_closed(void)
1713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1715 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001716}
1717
1718static int
1719kqueue_queue_internal_close(kqueue_queue_Object *self)
1720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 int save_errno = 0;
1722 if (self->kqfd >= 0) {
1723 int kqfd = self->kqfd;
1724 self->kqfd = -1;
1725 Py_BEGIN_ALLOW_THREADS
1726 if (close(kqfd) < 0)
1727 save_errno = errno;
1728 Py_END_ALLOW_THREADS
1729 }
1730 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001731}
1732
1733static PyObject *
1734newKqueue_Object(PyTypeObject *type, SOCKET fd)
1735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 kqueue_queue_Object *self;
1737 assert(type != NULL && type->tp_alloc != NULL);
1738 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1739 if (self == NULL) {
1740 return NULL;
1741 }
1742
1743 if (fd == -1) {
1744 Py_BEGIN_ALLOW_THREADS
1745 self->kqfd = kqueue();
1746 Py_END_ALLOW_THREADS
1747 }
1748 else {
1749 self->kqfd = fd;
1750 }
1751 if (self->kqfd < 0) {
1752 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001753 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 return NULL;
1755 }
1756 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001757}
1758
1759static PyObject *
1760kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1761{
1762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 if ((args != NULL && PyObject_Size(args)) ||
1764 (kwds != NULL && PyObject_Size(kwds))) {
1765 PyErr_SetString(PyExc_ValueError,
1766 "select.kqueue doesn't accept arguments");
1767 return NULL;
1768 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001771}
1772
1773static void
1774kqueue_queue_dealloc(kqueue_queue_Object *self)
1775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 kqueue_queue_internal_close(self);
1777 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001778}
1779
1780static PyObject*
1781kqueue_queue_close(kqueue_queue_Object *self)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 errno = kqueue_queue_internal_close(self);
1784 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001785 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 return NULL;
1787 }
1788 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001789}
1790
1791PyDoc_STRVAR(kqueue_queue_close_doc,
1792"close() -> None\n\
1793\n\
1794Close the kqueue control file descriptor. Further operations on the kqueue\n\
1795object will raise an exception.");
1796
1797static PyObject*
1798kqueue_queue_get_closed(kqueue_queue_Object *self)
1799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 if (self->kqfd < 0)
1801 Py_RETURN_TRUE;
1802 else
1803 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001804}
1805
1806static PyObject*
1807kqueue_queue_fileno(kqueue_queue_Object *self)
1808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 if (self->kqfd < 0)
1810 return kqueue_queue_err_closed();
1811 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001812}
1813
1814PyDoc_STRVAR(kqueue_queue_fileno_doc,
1815"fileno() -> int\n\
1816\n\
1817Return the kqueue control file descriptor.");
1818
1819static PyObject*
1820kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1825 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001828}
1829
1830PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1831"fromfd(fd) -> kqueue\n\
1832\n\
1833Create a kqueue object from a given control fd.");
1834
1835static PyObject *
1836kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1837{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 int nevents = 0;
1839 int gotevents = 0;
1840 int nchanges = 0;
1841 int i = 0;
1842 PyObject *otimeout = NULL;
1843 PyObject *ch = NULL;
1844 PyObject *it = NULL, *ei = NULL;
1845 PyObject *result = NULL;
1846 struct kevent *evl = NULL;
1847 struct kevent *chl = NULL;
1848 struct timespec timeoutspec;
1849 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (self->kqfd < 0)
1852 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1855 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 if (nevents < 0) {
1858 PyErr_Format(PyExc_ValueError,
1859 "Length of eventlist must be 0 or positive, got %d",
1860 nevents);
1861 return NULL;
1862 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (otimeout == Py_None || otimeout == NULL) {
1865 ptimeoutspec = NULL;
1866 }
1867 else if (PyNumber_Check(otimeout)) {
1868 double timeout;
1869 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 timeout = PyFloat_AsDouble(otimeout);
1872 if (timeout == -1 && PyErr_Occurred())
1873 return NULL;
1874 if (timeout > (double)LONG_MAX) {
1875 PyErr_SetString(PyExc_OverflowError,
1876 "timeout period too long");
1877 return NULL;
1878 }
1879 if (timeout < 0) {
1880 PyErr_SetString(PyExc_ValueError,
1881 "timeout must be positive or None");
1882 return NULL;
1883 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 seconds = (long)timeout;
1886 timeout = timeout - (double)seconds;
1887 timeoutspec.tv_sec = seconds;
1888 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1889 ptimeoutspec = &timeoutspec;
1890 }
1891 else {
1892 PyErr_Format(PyExc_TypeError,
1893 "timeout argument must be an number "
1894 "or None, got %.200s",
1895 Py_TYPE(otimeout)->tp_name);
1896 return NULL;
1897 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (ch != NULL && ch != Py_None) {
1900 it = PyObject_GetIter(ch);
1901 if (it == NULL) {
1902 PyErr_SetString(PyExc_TypeError,
1903 "changelist is not iterable");
1904 return NULL;
1905 }
1906 nchanges = PyObject_Size(ch);
1907 if (nchanges < 0) {
1908 goto error;
1909 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 chl = PyMem_New(struct kevent, nchanges);
1912 if (chl == NULL) {
1913 PyErr_NoMemory();
1914 goto error;
1915 }
1916 i = 0;
1917 while ((ei = PyIter_Next(it)) != NULL) {
1918 if (!kqueue_event_Check(ei)) {
1919 Py_DECREF(ei);
1920 PyErr_SetString(PyExc_TypeError,
1921 "changelist must be an iterable of "
1922 "select.kevent objects");
1923 goto error;
1924 } else {
1925 chl[i++] = ((kqueue_event_Object *)ei)->e;
1926 }
1927 Py_DECREF(ei);
1928 }
1929 }
1930 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 /* event list */
1933 if (nevents) {
1934 evl = PyMem_New(struct kevent, nevents);
1935 if (evl == NULL) {
1936 PyErr_NoMemory();
1937 goto error;
1938 }
1939 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 Py_BEGIN_ALLOW_THREADS
1942 gotevents = kevent(self->kqfd, chl, nchanges,
1943 evl, nevents, ptimeoutspec);
1944 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 if (gotevents == -1) {
1947 PyErr_SetFromErrno(PyExc_OSError);
1948 goto error;
1949 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 result = PyList_New(gotevents);
1952 if (result == NULL) {
1953 goto error;
1954 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 for (i = 0; i < gotevents; i++) {
1957 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1960 if (ch == NULL) {
1961 goto error;
1962 }
1963 ch->e = evl[i];
1964 PyList_SET_ITEM(result, i, (PyObject *)ch);
1965 }
1966 PyMem_Free(chl);
1967 PyMem_Free(evl);
1968 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001969
1970 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 PyMem_Free(chl);
1972 PyMem_Free(evl);
1973 Py_XDECREF(result);
1974 Py_XDECREF(it);
1975 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001976}
1977
1978PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001979"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001980\n\
1981Calls the kernel kevent function.\n\
1982- changelist must be a list of kevent objects describing the changes\n\
1983 to be made to the kernel's watch list or None.\n\
1984- max_events lets you specify the maximum number of events that the\n\
1985 kernel will return.\n\
1986- timeout is the maximum time to wait in seconds, or else None,\n\
1987 to wait forever. timeout accepts floats for smaller timeouts, too.");
1988
1989
1990static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1992 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1993 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1994 kqueue_queue_close_doc},
1995 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1996 kqueue_queue_fileno_doc},
1997 {"control", (PyCFunction)kqueue_queue_control,
1998 METH_VARARGS , kqueue_queue_control_doc},
1999 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002000};
2001
2002static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 {"closed", (getter)kqueue_queue_get_closed, NULL,
2004 "True if the kqueue handler is closed"},
2005 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002006};
2007
2008PyDoc_STRVAR(kqueue_queue_doc,
2009"Kqueue syscall wrapper.\n\
2010\n\
2011For example, to start watching a socket for input:\n\
2012>>> kq = kqueue()\n\
2013>>> sock = socket()\n\
2014>>> sock.connect((host, port))\n\
2015>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2016\n\
2017To wait one second for it to become writeable:\n\
2018>>> kq.control(None, 1, 1000)\n\
2019\n\
2020To stop listening:\n\
2021>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2022
2023static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 PyVarObject_HEAD_INIT(NULL, 0)
2025 "select.kqueue", /* tp_name */
2026 sizeof(kqueue_queue_Object), /* tp_basicsize */
2027 0, /* tp_itemsize */
2028 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2029 0, /* tp_print */
2030 0, /* tp_getattr */
2031 0, /* tp_setattr */
2032 0, /* tp_reserved */
2033 0, /* tp_repr */
2034 0, /* tp_as_number */
2035 0, /* tp_as_sequence */
2036 0, /* tp_as_mapping */
2037 0, /* tp_hash */
2038 0, /* tp_call */
2039 0, /* tp_str */
2040 0, /* tp_getattro */
2041 0, /* tp_setattro */
2042 0, /* tp_as_buffer */
2043 Py_TPFLAGS_DEFAULT, /* tp_flags */
2044 kqueue_queue_doc, /* tp_doc */
2045 0, /* tp_traverse */
2046 0, /* tp_clear */
2047 0, /* tp_richcompare */
2048 0, /* tp_weaklistoffset */
2049 0, /* tp_iter */
2050 0, /* tp_iternext */
2051 kqueue_queue_methods, /* tp_methods */
2052 0, /* tp_members */
2053 kqueue_queue_getsetlist, /* tp_getset */
2054 0, /* tp_base */
2055 0, /* tp_dict */
2056 0, /* tp_descr_get */
2057 0, /* tp_descr_set */
2058 0, /* tp_dictoffset */
2059 0, /* tp_init */
2060 0, /* tp_alloc */
2061 kqueue_queue_new, /* tp_new */
2062 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002063};
2064
2065#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002066
2067
2068
2069
2070
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002071/* ************************************************************************ */
2072
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002074"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2075\n\
2076Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002077The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002078rlist -- wait until ready for reading\n\
2079wlist -- wait until ready for writing\n\
2080xlist -- wait for an ``exceptional condition''\n\
2081If only one kind of condition is required, pass [] for the other lists.\n\
2082A file descriptor is either a socket or file object, or a small integer\n\
2083gotten from a fileno() method call on one of those.\n\
2084\n\
2085The optional 4th argument specifies a timeout in seconds; it may be\n\
2086a floating point number to specify fractions of seconds. If it is absent\n\
2087or None, the call will never time out.\n\
2088\n\
2089The return value is a tuple of three lists corresponding to the first three\n\
2090arguments; each contains the subset of the corresponding file descriptors\n\
2091that are ready.\n\
2092\n\
2093*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002094On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002095descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002096
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002097static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002099#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002101#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002102#ifdef HAVE_SYS_DEVPOLL_H
2103 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2104#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002106};
2107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002109"This module supports asynchronous I/O on multiple file descriptors.\n\
2110\n\
2111*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002112On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002113
Martin v. Löwis1a214512008-06-11 05:26:20 +00002114
2115static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 PyModuleDef_HEAD_INIT,
2117 "select",
2118 module_doc,
2119 -1,
2120 select_methods,
2121 NULL,
2122 NULL,
2123 NULL,
2124 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002125};
2126
Jesus Cead8b9ae62011-11-14 19:07:41 +01002127
2128
2129
Mark Hammond62b1ab12002-07-23 06:31:15 +00002130PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002131PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 PyObject *m;
2134 m = PyModule_Create(&selectmodule);
2135 if (m == NULL)
2136 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002137
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002138 Py_INCREF(PyExc_OSError);
2139 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002140
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002141#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002142#ifdef HAVE_BROKEN_PIPE_BUF
2143#undef PIPE_BUF
2144#define PIPE_BUF 512
2145#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002147#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002148
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002149#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002150#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (select_have_broken_poll()) {
2152 if (PyObject_DelAttrString(m, "poll") == -1) {
2153 PyErr_Clear();
2154 }
2155 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002156#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002158#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 if (PyType_Ready(&poll_Type) < 0)
2160 return NULL;
2161 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2162 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2163 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2164 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2165 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2166 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002167
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002168#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002170#endif
2171#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002173#endif
2174#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002176#endif
2177#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002179#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002180#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002182#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002184#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002185
Jesus Cead8b9ae62011-11-14 19:07:41 +01002186#ifdef HAVE_SYS_DEVPOLL_H
2187 if (PyType_Ready(&devpoll_Type) < 0)
2188 return NULL;
2189#endif
2190
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002191#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2193 if (PyType_Ready(&pyEpoll_Type) < 0)
2194 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 Py_INCREF(&pyEpoll_Type);
2197 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2200 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2201 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2202 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2203 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2204 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002205#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 /* Kernel 2.6.2+ */
2207 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002208#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2210 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2211 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2212 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2213 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2214 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002215
2216 PyModule_AddIntConstant(m, "EPOLL_CLOEXEC", EPOLL_CLOEXEC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002217#endif /* HAVE_EPOLL */
2218
2219#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 kqueue_event_Type.tp_new = PyType_GenericNew;
2221 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2222 if(PyType_Ready(&kqueue_event_Type) < 0)
2223 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 Py_INCREF(&kqueue_event_Type);
2226 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2229 if(PyType_Ready(&kqueue_queue_Type) < 0)
2230 return NULL;
2231 Py_INCREF(&kqueue_queue_Type);
2232 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2233
2234 /* event filters */
2235 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2236 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2237 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2238 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2239 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002240#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2244 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 /* event flags */
2247 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2248 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2249 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2250 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2251 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2252 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2255 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2258 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 /* READ WRITE filter flag */
2261 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 /* VNODE filter flags */
2264 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2265 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2266 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2267 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2268 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2269 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 /* PROC filter flags */
2273 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2274 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2275 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2276 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2277 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2280 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2281 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2282
2283 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002284#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2286 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2287 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002288#endif
2289
2290#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002292}