blob: 5d5e77248acafcaaa7b5bb8fffdd68293eb236d1 [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 *
1090newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
1091{
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 if (sizehint == -1) {
1095 sizehint = FD_SETSIZE-1;
1096 }
1097 else if (sizehint < 1) {
1098 PyErr_Format(PyExc_ValueError,
1099 "sizehint must be greater zero, got %d",
1100 sizehint);
1101 return NULL;
1102 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 assert(type != NULL && type->tp_alloc != NULL);
1105 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1106 if (self == NULL)
1107 return NULL;
1108
1109 if (fd == -1) {
1110 Py_BEGIN_ALLOW_THREADS
1111 self->epfd = epoll_create(sizehint);
1112 Py_END_ALLOW_THREADS
1113 }
1114 else {
1115 self->epfd = fd;
1116 }
1117 if (self->epfd < 0) {
1118 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001119 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 return NULL;
1121 }
1122 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001123}
1124
1125
1126static PyObject *
1127pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1128{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 int sizehint = -1;
1130 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
1133 &sizehint))
1134 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001137}
1138
1139
1140static void
1141pyepoll_dealloc(pyEpoll_Object *self)
1142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 (void)pyepoll_internal_close(self);
1144 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001145}
1146
1147static PyObject*
1148pyepoll_close(pyEpoll_Object *self)
1149{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 errno = pyepoll_internal_close(self);
1151 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001152 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 return NULL;
1154 }
1155 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001156}
1157
1158PyDoc_STRVAR(pyepoll_close_doc,
1159"close() -> None\n\
1160\n\
1161Close the epoll control file descriptor. Further operations on the epoll\n\
1162object will raise an exception.");
1163
1164static PyObject*
1165pyepoll_get_closed(pyEpoll_Object *self)
1166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 if (self->epfd < 0)
1168 Py_RETURN_TRUE;
1169 else
1170 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001171}
1172
1173static PyObject*
1174pyepoll_fileno(pyEpoll_Object *self)
1175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 if (self->epfd < 0)
1177 return pyepoll_err_closed();
1178 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001179}
1180
1181PyDoc_STRVAR(pyepoll_fileno_doc,
1182"fileno() -> int\n\
1183\n\
1184Return the epoll control file descriptor.");
1185
1186static PyObject*
1187pyepoll_fromfd(PyObject *cls, PyObject *args)
1188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1192 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001195}
1196
1197PyDoc_STRVAR(pyepoll_fromfd_doc,
1198"fromfd(fd) -> epoll\n\
1199\n\
1200Create an epoll object from a given control fd.");
1201
1202static PyObject *
1203pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 struct epoll_event ev;
1206 int result;
1207 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 if (epfd < 0)
1210 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 fd = PyObject_AsFileDescriptor(pfd);
1213 if (fd == -1) {
1214 return NULL;
1215 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 switch(op) {
1218 case EPOLL_CTL_ADD:
1219 case EPOLL_CTL_MOD:
1220 ev.events = events;
1221 ev.data.fd = fd;
1222 Py_BEGIN_ALLOW_THREADS
1223 result = epoll_ctl(epfd, op, fd, &ev);
1224 Py_END_ALLOW_THREADS
1225 break;
1226 case EPOLL_CTL_DEL:
1227 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1228 * operation required a non-NULL pointer in event, even
1229 * though this argument is ignored. */
1230 Py_BEGIN_ALLOW_THREADS
1231 result = epoll_ctl(epfd, op, fd, &ev);
1232 if (errno == EBADF) {
1233 /* fd already closed */
1234 result = 0;
1235 errno = 0;
1236 }
1237 Py_END_ALLOW_THREADS
1238 break;
1239 default:
1240 result = -1;
1241 errno = EINVAL;
1242 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001245 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 return NULL;
1247 }
1248 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001249}
1250
1251static PyObject *
1252pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 PyObject *pfd;
1255 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1256 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1259 &pfd, &events)) {
1260 return NULL;
1261 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001264}
1265
1266PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001267"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001268\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001269Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001270fd is the target file descriptor of the operation.\n\
1271events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001272is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1273\n\
1274The epoll interface supports all file descriptors that support poll.");
1275
1276static PyObject *
1277pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 PyObject *pfd;
1280 unsigned int events;
1281 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1284 &pfd, &events)) {
1285 return NULL;
1286 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001289}
1290
1291PyDoc_STRVAR(pyepoll_modify_doc,
1292"modify(fd, eventmask) -> None\n\
1293\n\
1294fd is the target file descriptor of the operation\n\
1295events is a bit set composed of the various EPOLL constants");
1296
1297static PyObject *
1298pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 PyObject *pfd;
1301 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1304 &pfd)) {
1305 return NULL;
1306 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001309}
1310
1311PyDoc_STRVAR(pyepoll_unregister_doc,
1312"unregister(fd) -> None\n\
1313\n\
1314fd is the target file descriptor of the operation.");
1315
1316static PyObject *
1317pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 double dtimeout = -1.;
1320 int timeout;
1321 int maxevents = -1;
1322 int nfds, i;
1323 PyObject *elist = NULL, *etuple = NULL;
1324 struct epoll_event *evs = NULL;
1325 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 if (self->epfd < 0)
1328 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1331 &dtimeout, &maxevents)) {
1332 return NULL;
1333 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 if (dtimeout < 0) {
1336 timeout = -1;
1337 }
1338 else if (dtimeout * 1000.0 > INT_MAX) {
1339 PyErr_SetString(PyExc_OverflowError,
1340 "timeout is too large");
1341 return NULL;
1342 }
1343 else {
1344 timeout = (int)(dtimeout * 1000.0);
1345 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 if (maxevents == -1) {
1348 maxevents = FD_SETSIZE-1;
1349 }
1350 else if (maxevents < 1) {
1351 PyErr_Format(PyExc_ValueError,
1352 "maxevents must be greater than 0, got %d",
1353 maxevents);
1354 return NULL;
1355 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 evs = PyMem_New(struct epoll_event, maxevents);
1358 if (evs == NULL) {
1359 Py_DECREF(self);
1360 PyErr_NoMemory();
1361 return NULL;
1362 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 Py_BEGIN_ALLOW_THREADS
1365 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1366 Py_END_ALLOW_THREADS
1367 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001368 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 goto error;
1370 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 elist = PyList_New(nfds);
1373 if (elist == NULL) {
1374 goto error;
1375 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 for (i = 0; i < nfds; i++) {
1378 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1379 if (etuple == NULL) {
1380 Py_CLEAR(elist);
1381 goto error;
1382 }
1383 PyList_SET_ITEM(elist, i, etuple);
1384 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001385
Christian Heimesf6cd9672008-03-26 13:45:42 +00001386 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyMem_Free(evs);
1388 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389}
1390
1391PyDoc_STRVAR(pyepoll_poll_doc,
1392"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1393\n\
1394Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1395in seconds (as float). -1 makes poll wait indefinitely.\n\
1396Up to maxevents are returned to the caller.");
1397
1398static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 {"fromfd", (PyCFunction)pyepoll_fromfd,
1400 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1401 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1402 pyepoll_close_doc},
1403 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1404 pyepoll_fileno_doc},
1405 {"modify", (PyCFunction)pyepoll_modify,
1406 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1407 {"register", (PyCFunction)pyepoll_register,
1408 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1409 {"unregister", (PyCFunction)pyepoll_unregister,
1410 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1411 {"poll", (PyCFunction)pyepoll_poll,
1412 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1413 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001414};
1415
1416static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 {"closed", (getter)pyepoll_get_closed, NULL,
1418 "True if the epoll handler is closed"},
1419 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001420};
1421
1422PyDoc_STRVAR(pyepoll_doc,
1423"select.epoll([sizehint=-1])\n\
1424\n\
1425Returns an epolling object\n\
1426\n\
1427sizehint must be a positive integer or -1 for the default size. The\n\
1428sizehint is used to optimize internal data structures. It doesn't limit\n\
1429the maximum number of monitored events.");
1430
1431static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 PyVarObject_HEAD_INIT(NULL, 0)
1433 "select.epoll", /* tp_name */
1434 sizeof(pyEpoll_Object), /* tp_basicsize */
1435 0, /* tp_itemsize */
1436 (destructor)pyepoll_dealloc, /* tp_dealloc */
1437 0, /* tp_print */
1438 0, /* tp_getattr */
1439 0, /* tp_setattr */
1440 0, /* tp_reserved */
1441 0, /* tp_repr */
1442 0, /* tp_as_number */
1443 0, /* tp_as_sequence */
1444 0, /* tp_as_mapping */
1445 0, /* tp_hash */
1446 0, /* tp_call */
1447 0, /* tp_str */
1448 PyObject_GenericGetAttr, /* tp_getattro */
1449 0, /* tp_setattro */
1450 0, /* tp_as_buffer */
1451 Py_TPFLAGS_DEFAULT, /* tp_flags */
1452 pyepoll_doc, /* tp_doc */
1453 0, /* tp_traverse */
1454 0, /* tp_clear */
1455 0, /* tp_richcompare */
1456 0, /* tp_weaklistoffset */
1457 0, /* tp_iter */
1458 0, /* tp_iternext */
1459 pyepoll_methods, /* tp_methods */
1460 0, /* tp_members */
1461 pyepoll_getsetlist, /* tp_getset */
1462 0, /* tp_base */
1463 0, /* tp_dict */
1464 0, /* tp_descr_get */
1465 0, /* tp_descr_set */
1466 0, /* tp_dictoffset */
1467 0, /* tp_init */
1468 0, /* tp_alloc */
1469 pyepoll_new, /* tp_new */
1470 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471};
1472
1473#endif /* HAVE_EPOLL */
1474
1475#ifdef HAVE_KQUEUE
1476/* **************************************************************************
1477 * kqueue interface for BSD
1478 *
1479 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1480 * All rights reserved.
1481 *
1482 * Redistribution and use in source and binary forms, with or without
1483 * modification, are permitted provided that the following conditions
1484 * are met:
1485 * 1. Redistributions of source code must retain the above copyright
1486 * notice, this list of conditions and the following disclaimer.
1487 * 2. Redistributions in binary form must reproduce the above copyright
1488 * notice, this list of conditions and the following disclaimer in the
1489 * documentation and/or other materials provided with the distribution.
1490 *
1491 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1492 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1493 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1494 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1495 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1496 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1497 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1498 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1499 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1500 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1501 * SUCH DAMAGE.
1502 */
1503
1504#ifdef HAVE_SYS_EVENT_H
1505#include <sys/event.h>
1506#endif
1507
1508PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001509"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001510\n\
1511This object is the equivalent of the struct kevent for the C API.\n\
1512\n\
1513See the kqueue manpage for more detailed information about the meaning\n\
1514of the arguments.\n\
1515\n\
1516One minor note: while you might hope that udata could store a\n\
1517reference to a python object, it cannot, because it is impossible to\n\
1518keep a proper reference count of the object once it's passed into the\n\
1519kernel. Therefore, I have restricted it to only storing an integer. I\n\
1520recommend ignoring it and simply using the 'ident' field to key off\n\
1521of. You could also set up a dictionary on the python side to store a\n\
1522udata->object mapping.");
1523
1524typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 PyObject_HEAD
1526 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001527} kqueue_event_Object;
1528
1529static PyTypeObject kqueue_event_Type;
1530
1531#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1532
1533typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 PyObject_HEAD
1535 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001536} kqueue_queue_Object;
1537
1538static PyTypeObject kqueue_queue_Type;
1539
1540#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1541
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001542#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1543# error uintptr_t does not match void *!
1544#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1545# define T_UINTPTRT T_ULONGLONG
1546# define T_INTPTRT T_LONGLONG
1547# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1548# define UINTPTRT_FMT_UNIT "K"
1549# define INTPTRT_FMT_UNIT "L"
1550#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1551# define T_UINTPTRT T_ULONG
1552# define T_INTPTRT T_LONG
1553# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1554# define UINTPTRT_FMT_UNIT "k"
1555# define INTPTRT_FMT_UNIT "l"
1556#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1557# define T_UINTPTRT T_UINT
1558# define T_INTPTRT T_INT
1559# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1560# define UINTPTRT_FMT_UNIT "I"
1561# define INTPTRT_FMT_UNIT "i"
1562#else
1563# error uintptr_t does not match int, long, or long long!
1564#endif
1565
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001566/* Unfortunately, we can't store python objects in udata, because
1567 * kevents in the kernel can be removed without warning, which would
1568 * forever lose the refcount on the object stored with it.
1569 */
1570
1571#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1572static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1574 {"filter", T_SHORT, KQ_OFF(e.filter)},
1575 {"flags", T_USHORT, KQ_OFF(e.flags)},
1576 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1577 {"data", T_INTPTRT, KQ_OFF(e.data)},
1578 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1579 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001580};
1581#undef KQ_OFF
1582
1583static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001584
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001585kqueue_event_repr(kqueue_event_Object *s)
1586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 char buf[1024];
1588 PyOS_snprintf(
1589 buf, sizeof(buf),
1590 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1591 "data=0x%zd udata=%p>",
1592 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1593 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1594 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001595}
1596
1597static int
1598kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 PyObject *pfd;
1601 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1602 "data", "udata", NULL};
1603 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1608 &pfd, &(self->e.filter), &(self->e.flags),
1609 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1610 return -1;
1611 }
1612
1613 if (PyLong_Check(pfd)) {
1614 self->e.ident = PyLong_AsUintptr_t(pfd);
1615 }
1616 else {
1617 self->e.ident = PyObject_AsFileDescriptor(pfd);
1618 }
1619 if (PyErr_Occurred()) {
1620 return -1;
1621 }
1622 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001623}
1624
1625static PyObject *
1626kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 if (!kqueue_event_Check(o)) {
1632 if (op == Py_EQ || op == Py_NE) {
1633 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1634 Py_INCREF(res);
1635 return res;
1636 }
1637 PyErr_Format(PyExc_TypeError,
1638 "can't compare %.200s to %.200s",
1639 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1640 return NULL;
1641 }
1642 if (((result = s->e.ident - o->e.ident) == 0) &&
1643 ((result = s->e.filter - o->e.filter) == 0) &&
1644 ((result = s->e.flags - o->e.flags) == 0) &&
1645 ((result = s->e.fflags - o->e.fflags) == 0) &&
1646 ((result = s->e.data - o->e.data) == 0) &&
1647 ((result = s->e.udata - o->e.udata) == 0)
1648 ) {
1649 result = 0;
1650 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 switch (op) {
1653 case Py_EQ:
1654 result = (result == 0);
1655 break;
1656 case Py_NE:
1657 result = (result != 0);
1658 break;
1659 case Py_LE:
1660 result = (result <= 0);
1661 break;
1662 case Py_GE:
1663 result = (result >= 0);
1664 break;
1665 case Py_LT:
1666 result = (result < 0);
1667 break;
1668 case Py_GT:
1669 result = (result > 0);
1670 break;
1671 }
1672 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001673}
1674
1675static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 PyVarObject_HEAD_INIT(NULL, 0)
1677 "select.kevent", /* tp_name */
1678 sizeof(kqueue_event_Object), /* tp_basicsize */
1679 0, /* tp_itemsize */
1680 0, /* tp_dealloc */
1681 0, /* tp_print */
1682 0, /* tp_getattr */
1683 0, /* tp_setattr */
1684 0, /* tp_reserved */
1685 (reprfunc)kqueue_event_repr, /* tp_repr */
1686 0, /* tp_as_number */
1687 0, /* tp_as_sequence */
1688 0, /* tp_as_mapping */
1689 0, /* tp_hash */
1690 0, /* tp_call */
1691 0, /* tp_str */
1692 0, /* tp_getattro */
1693 0, /* tp_setattro */
1694 0, /* tp_as_buffer */
1695 Py_TPFLAGS_DEFAULT, /* tp_flags */
1696 kqueue_event_doc, /* tp_doc */
1697 0, /* tp_traverse */
1698 0, /* tp_clear */
1699 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1700 0, /* tp_weaklistoffset */
1701 0, /* tp_iter */
1702 0, /* tp_iternext */
1703 0, /* tp_methods */
1704 kqueue_event_members, /* tp_members */
1705 0, /* tp_getset */
1706 0, /* tp_base */
1707 0, /* tp_dict */
1708 0, /* tp_descr_get */
1709 0, /* tp_descr_set */
1710 0, /* tp_dictoffset */
1711 (initproc)kqueue_event_init, /* tp_init */
1712 0, /* tp_alloc */
1713 0, /* tp_new */
1714 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001715};
1716
1717static PyObject *
1718kqueue_queue_err_closed(void)
1719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1721 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001722}
1723
1724static int
1725kqueue_queue_internal_close(kqueue_queue_Object *self)
1726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 int save_errno = 0;
1728 if (self->kqfd >= 0) {
1729 int kqfd = self->kqfd;
1730 self->kqfd = -1;
1731 Py_BEGIN_ALLOW_THREADS
1732 if (close(kqfd) < 0)
1733 save_errno = errno;
1734 Py_END_ALLOW_THREADS
1735 }
1736 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001737}
1738
1739static PyObject *
1740newKqueue_Object(PyTypeObject *type, SOCKET fd)
1741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 kqueue_queue_Object *self;
1743 assert(type != NULL && type->tp_alloc != NULL);
1744 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1745 if (self == NULL) {
1746 return NULL;
1747 }
1748
1749 if (fd == -1) {
1750 Py_BEGIN_ALLOW_THREADS
1751 self->kqfd = kqueue();
1752 Py_END_ALLOW_THREADS
1753 }
1754 else {
1755 self->kqfd = fd;
1756 }
1757 if (self->kqfd < 0) {
1758 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001759 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 return NULL;
1761 }
1762 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001763}
1764
1765static PyObject *
1766kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1767{
1768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 if ((args != NULL && PyObject_Size(args)) ||
1770 (kwds != NULL && PyObject_Size(kwds))) {
1771 PyErr_SetString(PyExc_ValueError,
1772 "select.kqueue doesn't accept arguments");
1773 return NULL;
1774 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001777}
1778
1779static void
1780kqueue_queue_dealloc(kqueue_queue_Object *self)
1781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 kqueue_queue_internal_close(self);
1783 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001784}
1785
1786static PyObject*
1787kqueue_queue_close(kqueue_queue_Object *self)
1788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 errno = kqueue_queue_internal_close(self);
1790 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001791 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 return NULL;
1793 }
1794 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001795}
1796
1797PyDoc_STRVAR(kqueue_queue_close_doc,
1798"close() -> None\n\
1799\n\
1800Close the kqueue control file descriptor. Further operations on the kqueue\n\
1801object will raise an exception.");
1802
1803static PyObject*
1804kqueue_queue_get_closed(kqueue_queue_Object *self)
1805{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 if (self->kqfd < 0)
1807 Py_RETURN_TRUE;
1808 else
1809 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001810}
1811
1812static PyObject*
1813kqueue_queue_fileno(kqueue_queue_Object *self)
1814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 if (self->kqfd < 0)
1816 return kqueue_queue_err_closed();
1817 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001818}
1819
1820PyDoc_STRVAR(kqueue_queue_fileno_doc,
1821"fileno() -> int\n\
1822\n\
1823Return the kqueue control file descriptor.");
1824
1825static PyObject*
1826kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1831 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001834}
1835
1836PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1837"fromfd(fd) -> kqueue\n\
1838\n\
1839Create a kqueue object from a given control fd.");
1840
1841static PyObject *
1842kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 int nevents = 0;
1845 int gotevents = 0;
1846 int nchanges = 0;
1847 int i = 0;
1848 PyObject *otimeout = NULL;
1849 PyObject *ch = NULL;
1850 PyObject *it = NULL, *ei = NULL;
1851 PyObject *result = NULL;
1852 struct kevent *evl = NULL;
1853 struct kevent *chl = NULL;
1854 struct timespec timeoutspec;
1855 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 if (self->kqfd < 0)
1858 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1861 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (nevents < 0) {
1864 PyErr_Format(PyExc_ValueError,
1865 "Length of eventlist must be 0 or positive, got %d",
1866 nevents);
1867 return NULL;
1868 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 if (otimeout == Py_None || otimeout == NULL) {
1871 ptimeoutspec = NULL;
1872 }
1873 else if (PyNumber_Check(otimeout)) {
1874 double timeout;
1875 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 timeout = PyFloat_AsDouble(otimeout);
1878 if (timeout == -1 && PyErr_Occurred())
1879 return NULL;
1880 if (timeout > (double)LONG_MAX) {
1881 PyErr_SetString(PyExc_OverflowError,
1882 "timeout period too long");
1883 return NULL;
1884 }
1885 if (timeout < 0) {
1886 PyErr_SetString(PyExc_ValueError,
1887 "timeout must be positive or None");
1888 return NULL;
1889 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 seconds = (long)timeout;
1892 timeout = timeout - (double)seconds;
1893 timeoutspec.tv_sec = seconds;
1894 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1895 ptimeoutspec = &timeoutspec;
1896 }
1897 else {
1898 PyErr_Format(PyExc_TypeError,
1899 "timeout argument must be an number "
1900 "or None, got %.200s",
1901 Py_TYPE(otimeout)->tp_name);
1902 return NULL;
1903 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 if (ch != NULL && ch != Py_None) {
1906 it = PyObject_GetIter(ch);
1907 if (it == NULL) {
1908 PyErr_SetString(PyExc_TypeError,
1909 "changelist is not iterable");
1910 return NULL;
1911 }
1912 nchanges = PyObject_Size(ch);
1913 if (nchanges < 0) {
1914 goto error;
1915 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 chl = PyMem_New(struct kevent, nchanges);
1918 if (chl == NULL) {
1919 PyErr_NoMemory();
1920 goto error;
1921 }
1922 i = 0;
1923 while ((ei = PyIter_Next(it)) != NULL) {
1924 if (!kqueue_event_Check(ei)) {
1925 Py_DECREF(ei);
1926 PyErr_SetString(PyExc_TypeError,
1927 "changelist must be an iterable of "
1928 "select.kevent objects");
1929 goto error;
1930 } else {
1931 chl[i++] = ((kqueue_event_Object *)ei)->e;
1932 }
1933 Py_DECREF(ei);
1934 }
1935 }
1936 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 /* event list */
1939 if (nevents) {
1940 evl = PyMem_New(struct kevent, nevents);
1941 if (evl == NULL) {
1942 PyErr_NoMemory();
1943 goto error;
1944 }
1945 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 Py_BEGIN_ALLOW_THREADS
1948 gotevents = kevent(self->kqfd, chl, nchanges,
1949 evl, nevents, ptimeoutspec);
1950 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 if (gotevents == -1) {
1953 PyErr_SetFromErrno(PyExc_OSError);
1954 goto error;
1955 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 result = PyList_New(gotevents);
1958 if (result == NULL) {
1959 goto error;
1960 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 for (i = 0; i < gotevents; i++) {
1963 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1966 if (ch == NULL) {
1967 goto error;
1968 }
1969 ch->e = evl[i];
1970 PyList_SET_ITEM(result, i, (PyObject *)ch);
1971 }
1972 PyMem_Free(chl);
1973 PyMem_Free(evl);
1974 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001975
1976 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 PyMem_Free(chl);
1978 PyMem_Free(evl);
1979 Py_XDECREF(result);
1980 Py_XDECREF(it);
1981 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001982}
1983
1984PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001985"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001986\n\
1987Calls the kernel kevent function.\n\
1988- changelist must be a list of kevent objects describing the changes\n\
1989 to be made to the kernel's watch list or None.\n\
1990- max_events lets you specify the maximum number of events that the\n\
1991 kernel will return.\n\
1992- timeout is the maximum time to wait in seconds, or else None,\n\
1993 to wait forever. timeout accepts floats for smaller timeouts, too.");
1994
1995
1996static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1998 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1999 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2000 kqueue_queue_close_doc},
2001 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2002 kqueue_queue_fileno_doc},
2003 {"control", (PyCFunction)kqueue_queue_control,
2004 METH_VARARGS , kqueue_queue_control_doc},
2005 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002006};
2007
2008static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 {"closed", (getter)kqueue_queue_get_closed, NULL,
2010 "True if the kqueue handler is closed"},
2011 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002012};
2013
2014PyDoc_STRVAR(kqueue_queue_doc,
2015"Kqueue syscall wrapper.\n\
2016\n\
2017For example, to start watching a socket for input:\n\
2018>>> kq = kqueue()\n\
2019>>> sock = socket()\n\
2020>>> sock.connect((host, port))\n\
2021>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2022\n\
2023To wait one second for it to become writeable:\n\
2024>>> kq.control(None, 1, 1000)\n\
2025\n\
2026To stop listening:\n\
2027>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2028
2029static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 PyVarObject_HEAD_INIT(NULL, 0)
2031 "select.kqueue", /* tp_name */
2032 sizeof(kqueue_queue_Object), /* tp_basicsize */
2033 0, /* tp_itemsize */
2034 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2035 0, /* tp_print */
2036 0, /* tp_getattr */
2037 0, /* tp_setattr */
2038 0, /* tp_reserved */
2039 0, /* tp_repr */
2040 0, /* tp_as_number */
2041 0, /* tp_as_sequence */
2042 0, /* tp_as_mapping */
2043 0, /* tp_hash */
2044 0, /* tp_call */
2045 0, /* tp_str */
2046 0, /* tp_getattro */
2047 0, /* tp_setattro */
2048 0, /* tp_as_buffer */
2049 Py_TPFLAGS_DEFAULT, /* tp_flags */
2050 kqueue_queue_doc, /* tp_doc */
2051 0, /* tp_traverse */
2052 0, /* tp_clear */
2053 0, /* tp_richcompare */
2054 0, /* tp_weaklistoffset */
2055 0, /* tp_iter */
2056 0, /* tp_iternext */
2057 kqueue_queue_methods, /* tp_methods */
2058 0, /* tp_members */
2059 kqueue_queue_getsetlist, /* tp_getset */
2060 0, /* tp_base */
2061 0, /* tp_dict */
2062 0, /* tp_descr_get */
2063 0, /* tp_descr_set */
2064 0, /* tp_dictoffset */
2065 0, /* tp_init */
2066 0, /* tp_alloc */
2067 kqueue_queue_new, /* tp_new */
2068 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002069};
2070
2071#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002072
2073
2074
2075
2076
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002077/* ************************************************************************ */
2078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002080"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2081\n\
2082Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002083The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002084rlist -- wait until ready for reading\n\
2085wlist -- wait until ready for writing\n\
2086xlist -- wait for an ``exceptional condition''\n\
2087If only one kind of condition is required, pass [] for the other lists.\n\
2088A file descriptor is either a socket or file object, or a small integer\n\
2089gotten from a fileno() method call on one of those.\n\
2090\n\
2091The optional 4th argument specifies a timeout in seconds; it may be\n\
2092a floating point number to specify fractions of seconds. If it is absent\n\
2093or None, the call will never time out.\n\
2094\n\
2095The return value is a tuple of three lists corresponding to the first three\n\
2096arguments; each contains the subset of the corresponding file descriptors\n\
2097that are ready.\n\
2098\n\
2099*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002100On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002101descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002102
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002103static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002105#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002107#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002108#ifdef HAVE_SYS_DEVPOLL_H
2109 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2110#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002112};
2113
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002114PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002115"This module supports asynchronous I/O on multiple file descriptors.\n\
2116\n\
2117*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002118On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002119
Martin v. Löwis1a214512008-06-11 05:26:20 +00002120
2121static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 PyModuleDef_HEAD_INIT,
2123 "select",
2124 module_doc,
2125 -1,
2126 select_methods,
2127 NULL,
2128 NULL,
2129 NULL,
2130 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002131};
2132
Jesus Cead8b9ae62011-11-14 19:07:41 +01002133
2134
2135
Mark Hammond62b1ab12002-07-23 06:31:15 +00002136PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002137PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 PyObject *m;
2140 m = PyModule_Create(&selectmodule);
2141 if (m == NULL)
2142 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002143
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002144 Py_INCREF(PyExc_OSError);
2145 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002146
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002147#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002148#ifdef HAVE_BROKEN_PIPE_BUF
2149#undef PIPE_BUF
2150#define PIPE_BUF 512
2151#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002153#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002154
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002155#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002156#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 if (select_have_broken_poll()) {
2158 if (PyObject_DelAttrString(m, "poll") == -1) {
2159 PyErr_Clear();
2160 }
2161 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002162#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002164#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 if (PyType_Ready(&poll_Type) < 0)
2166 return NULL;
2167 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
2168 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
2169 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
2170 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
2171 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
2172 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002173
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002174#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002176#endif
2177#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002179#endif
2180#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002182#endif
2183#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002185#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002186#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002188#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002190#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002191
Jesus Cead8b9ae62011-11-14 19:07:41 +01002192#ifdef HAVE_SYS_DEVPOLL_H
2193 if (PyType_Ready(&devpoll_Type) < 0)
2194 return NULL;
2195#endif
2196
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002197#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2199 if (PyType_Ready(&pyEpoll_Type) < 0)
2200 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 Py_INCREF(&pyEpoll_Type);
2203 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
2206 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
2207 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
2208 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
2209 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
2210 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002211#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 /* Kernel 2.6.2+ */
2213 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002214#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
2216 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
2217 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
2218 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
2219 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
2220 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002221#endif /* HAVE_EPOLL */
2222
2223#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 kqueue_event_Type.tp_new = PyType_GenericNew;
2225 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2226 if(PyType_Ready(&kqueue_event_Type) < 0)
2227 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 Py_INCREF(&kqueue_event_Type);
2230 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2233 if(PyType_Ready(&kqueue_queue_Type) < 0)
2234 return NULL;
2235 Py_INCREF(&kqueue_queue_Type);
2236 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2237
2238 /* event filters */
2239 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2240 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2241 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2242 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2243 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2248 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 /* event flags */
2251 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2252 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2253 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2254 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2255 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2256 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2259 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2262 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 /* READ WRITE filter flag */
2265 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 /* VNODE filter flags */
2268 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2269 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2270 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2271 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2272 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2273 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2274 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 /* PROC filter flags */
2277 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2278 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2279 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2280 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2281 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2284 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2285 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2286
2287 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002288#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2290 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2291 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002292#endif
2293
2294#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002296}