blob: 1c021ba61b678745d90c1b05f9107a4e81a131e9 [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /* Perform runtime testing for a broken poll on OSX to make it easier
12 * to use the same binary on multiple releases of the OS.
13 */
14#undef HAVE_BROKEN_POLL
15#endif
16
Tim Petersd92dfe02000-12-12 01:18:41 +000017/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
18 64 is too small (too many people have bumped into that limit).
19 Here we boost it.
20 Users who want even more than the boosted limit should #define
21 FD_SETSIZE higher before this; e.g., via compiler /D switch.
22*/
23#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
24#define FD_SETSIZE 512
25#endif
26
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000027#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#elif defined(HAVE_SYS_POLL_H)
30#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000031#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000032
Guido van Rossum37273171996-12-09 18:47:43 +000033#ifdef __sgi
34/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000035extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000036#endif
37
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000040#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000041
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000042#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000043#include <sys/time.h>
44#include <utils.h>
45#endif
46
Guido van Rossum6f489d91996-06-28 20:15:15 +000047#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000048# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000050#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051# define SOCKET int
Skip Montanaroeb33e5a2007-08-17 12:57:41 +000052# if defined(__VMS)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053# include <socket.h>
54# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000057static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000058
Barry Warsawc1cb3601996-12-12 22:16:21 +000059/* list of Python objects and their file descriptor */
60typedef struct {
61 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000062 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000063 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000064} pylist;
65
Barry Warsawc1cb3601996-12-12 22:16:21 +000066static void
Tim Peters4b046c22001-08-16 21:59:46 +000067reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000068{
69 int i;
Tim Peters4b046c22001-08-16 21:59:46 +000070 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000071 Py_XDECREF(fd2obj[i].obj);
72 fd2obj[i].obj = NULL;
73 }
74 fd2obj[0].sentinel = -1;
75}
76
77
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000078/* returns -1 and sets the Python exception if an error occurred, otherwise
79 returns a number >= 0
80*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000081static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000082seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000083{
Barry Warsawc1cb3601996-12-12 22:16:21 +000084 int i;
85 int max = -1;
86 int index = 0;
Brett Cannon62dba4c2003-09-10 19:37:42 +000087 int len = -1;
88 PyObject* fast_seq = NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +000089 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000092 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Brett Cannon62dba4c2003-09-10 19:37:42 +000094 fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
95 if (!fast_seq)
96 return -1;
97
98 len = PySequence_Fast_GET_SIZE(fast_seq);
99
Barry Warsawc1cb3601996-12-12 22:16:21 +0000100 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +0000105 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +0000106
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +0000108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112 max = 0; /* not used for Win32 */
113#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000114 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000134 }
Brett Cannon62dba4c2003-09-10 19:37:42 +0000135 Py_DECREF(fast_seq);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000136 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137
138 finally:
139 Py_XDECREF(o);
Brett Cannon62dba4c2003-09-10 19:37:42 +0000140 Py_DECREF(fast_seq);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000141 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000142}
143
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144/* returns NULL and sets the Python exception if an error occurred */
145static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000146set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000147{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000148 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Barry Warsawc1cb3601996-12-12 22:16:21 +0000152 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000153 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000154 count++;
155 }
156 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157 if (!list)
158 return NULL;
159
Barry Warsawc1cb3601996-12-12 22:16:21 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000164#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000165 if (fd > FD_SETSIZE) {
166 PyErr_SetString(PyExc_SystemError,
167 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000169 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000170#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000171 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 fd2obj[j].obj = NULL;
173 /* transfer ownership */
174 if (PyList_SetItem(list, i, o) < 0)
175 goto finally;
176
177 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000178 }
179 }
180 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000181 finally:
182 Py_DECREF(list);
183 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000184}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000185
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#undef SELECT_USES_HEAP
187#if FD_SETSIZE > 1024
188#define SELECT_USES_HEAP
189#endif /* FD_SETSIZE > 1024 */
190
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000191static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000192select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000193{
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000195 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000196#else /* !SELECT_USES_HEAP */
Tim Peters4b046c22001-08-16 21:59:46 +0000197 /* XXX: All this should probably be implemented as follows:
Barry Warsawb44740f2001-08-16 16:52:59 +0000198 * - find the highest descriptor we're interested in
199 * - add one
200 * - that's the size
201 * See: Stevens, APitUE, $12.5.1
202 */
Tim Peters4b046c22001-08-16 21:59:46 +0000203 pylist rfd2obj[FD_SETSIZE + 1];
204 pylist wfd2obj[FD_SETSIZE + 1];
205 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000206#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000207 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000208 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000209 PyObject *tout = Py_None;
210 fd_set ifdset, ofdset, efdset;
211 double timeout;
212 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000213 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000214 int imax, omax, emax, max;
215 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000216
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000217 /* convert arguments */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000218 if (!PyArg_UnpackTuple(args, "select", 3, 4,
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000219 &ifdlist, &ofdlist, &efdlist, &tout))
220 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000221
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000222 if (tout == Py_None)
223 tvp = (struct timeval *)0;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000224 else if (!PyNumber_Check(tout)) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000225 PyErr_SetString(PyExc_TypeError,
226 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000227 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000228 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000229 else {
Neil Schemenauer47ec6c02002-11-18 16:02:29 +0000230 timeout = PyFloat_AsDouble(tout);
231 if (timeout == -1 && PyErr_Occurred())
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000232 return NULL;
Guido van Rossum3262e162000-06-28 21:18:13 +0000233 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000234 PyErr_SetString(PyExc_OverflowError,
235 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000236 return NULL;
237 }
238 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000239 timeout = timeout - (double)seconds;
240 tv.tv_sec = seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000241 tv.tv_usec = (long)(timeout * 1E6);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000242 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000243 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000244
Guido van Rossumed233a51992-06-23 09:07:03 +0000245
Barry Warsawb44740f2001-08-16 16:52:59 +0000246#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000247 /* Allocate memory for the lists */
Tim Peters4b046c22001-08-16 21:59:46 +0000248 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
249 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
250 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000251 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000252 if (rfd2obj) PyMem_DEL(rfd2obj);
253 if (wfd2obj) PyMem_DEL(wfd2obj);
254 if (efd2obj) PyMem_DEL(efd2obj);
Tim Peters5f322d32003-02-11 17:18:58 +0000255 return PyErr_NoMemory();
Guido van Rossumd20781b1998-07-02 02:53:36 +0000256 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000257#endif /* SELECT_USES_HEAP */
Brett Cannon62dba4c2003-09-10 19:37:42 +0000258 /* Convert sequences to fd_sets, and get maximum fd number
259 * propagates the Python exception set in seq2set()
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000260 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000261 rfd2obj[0].sentinel = -1;
262 wfd2obj[0].sentinel = -1;
263 efd2obj[0].sentinel = -1;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000264 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000265 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000266 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000267 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000268 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000269 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000270 max = imax;
271 if (omax > max) max = omax;
272 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000273
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 Py_BEGIN_ALLOW_THREADS
275 n = select(max, &ifdset, &ofdset, &efdset, tvp);
276 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000277
Thomas Heller106f4c72002-09-24 16:51:00 +0000278#ifdef MS_WINDOWS
279 if (n == SOCKET_ERROR) {
280 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
281 }
282#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000283 if (n < 0) {
284 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000285 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000286#endif
Barry Warsawc1cb3601996-12-12 22:16:21 +0000287 else {
288 /* any of these three calls can raise an exception. it's more
289 convenient to test for this after all three calls... but
290 is that acceptable?
291 */
292 ifdlist = set2list(&ifdset, rfd2obj);
293 ofdlist = set2list(&ofdset, wfd2obj);
294 efdlist = set2list(&efdset, efd2obj);
295 if (PyErr_Occurred())
296 ret = NULL;
297 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +0000298 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000299
Barry Warsawc1cb3601996-12-12 22:16:21 +0000300 Py_DECREF(ifdlist);
301 Py_DECREF(ofdlist);
302 Py_DECREF(efdlist);
303 }
304
305 finally:
306 reap_obj(rfd2obj);
307 reap_obj(wfd2obj);
308 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000309#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000310 PyMem_DEL(rfd2obj);
311 PyMem_DEL(wfd2obj);
312 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000313#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000314 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000315}
316
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000317#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000318/*
319 * poll() support
320 */
321
322typedef struct {
323 PyObject_HEAD
324 PyObject *dict;
325 int ufd_uptodate;
326 int ufd_len;
327 struct pollfd *ufds;
328} pollObject;
329
Jeremy Hylton938ace62002-07-17 16:30:39 +0000330static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331
332/* Update the malloc'ed array of pollfds to match the dictionary
333 contained within a pollObject. Return 1 on success, 0 on an error.
334*/
335
336static int
337update_ufd_array(pollObject *self)
338{
Martin v. Löwis18e16552006-02-15 17:27:45 +0000339 Py_ssize_t i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000340 PyObject *key, *value;
Georg Brandld492ad82008-07-23 16:13:07 +0000341 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000342
343 self->ufd_len = PyDict_Size(self->dict);
Georg Brandld492ad82008-07-23 16:13:07 +0000344 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000345 if (self->ufds == NULL) {
Georg Brandld492ad82008-07-23 16:13:07 +0000346 self->ufds = old_ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000347 PyErr_NoMemory();
348 return 0;
349 }
350
351 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000352 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Christian Heimes217cfd12007-12-02 14:31:20 +0000353 self->ufds[i].fd = PyLong_AsLong(key);
354 self->ufds[i].events = (short)PyLong_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000355 i++;
356 }
357 self->ufd_uptodate = 1;
358 return 1;
359}
360
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000361PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362"register(fd [, eventmask] ) -> None\n\n\
363Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000364fd -- either an integer, or an object with a fileno() method returning an\n\
365 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000366events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367
368static PyObject *
369poll_register(pollObject *self, PyObject *args)
370{
371 PyObject *o, *key, *value;
372 int fd, events = POLLIN | POLLPRI | POLLOUT;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000373 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374
Fred Drake7b87f852001-05-21 03:29:05 +0000375 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000376 return NULL;
377 }
378
379 fd = PyObject_AsFileDescriptor(o);
380 if (fd == -1) return NULL;
381
382 /* Add entry to the internal dictionary: the key is the
383 file descriptor, and the value is the event mask. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000384 key = PyLong_FromLong(fd);
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000385 if (key == NULL)
386 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +0000387 value = PyLong_FromLong(events);
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000388 if (value == NULL) {
389 Py_DECREF(key);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000390 return NULL;
391 }
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000392 err = PyDict_SetItem(self->dict, key, value);
393 Py_DECREF(key);
394 Py_DECREF(value);
395 if (err < 0)
396 return NULL;
397
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000398 self->ufd_uptodate = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000399
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400 Py_INCREF(Py_None);
401 return Py_None;
402}
403
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000404PyDoc_STRVAR(poll_modify_doc,
405"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000406Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000407fd -- either an integer, or an object with a fileno() method returning an\n\
408 int.\n\
409events -- an optional bitmask describing the type of events to check for");
410
411static PyObject *
412poll_modify(pollObject *self, PyObject *args)
413{
414 PyObject *o, *key, *value;
415 int fd, events;
416 int err;
417
418 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
419 return NULL;
420 }
421
422 fd = PyObject_AsFileDescriptor(o);
423 if (fd == -1) return NULL;
424
425 /* Modify registered fd */
426 key = PyLong_FromLong(fd);
427 if (key == NULL)
428 return NULL;
429 if (PyDict_GetItem(self->dict, key) == NULL) {
430 errno = ENOENT;
431 PyErr_SetFromErrno(PyExc_IOError);
432 return NULL;
433 }
434 value = PyLong_FromLong(events);
435 if (value == NULL) {
436 Py_DECREF(key);
437 return NULL;
438 }
439 err = PyDict_SetItem(self->dict, key, value);
440 Py_DECREF(key);
441 Py_DECREF(value);
442 if (err < 0)
443 return NULL;
444
445 self->ufd_uptodate = 0;
446
447 Py_INCREF(Py_None);
448 return Py_None;
449}
450
451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000452PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000453"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000454Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455
456static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000457poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000458{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000459 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000460 int fd;
461
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462 fd = PyObject_AsFileDescriptor( o );
463 if (fd == -1)
464 return NULL;
465
466 /* Check whether the fd is already in the array */
Christian Heimes217cfd12007-12-02 14:31:20 +0000467 key = PyLong_FromLong(fd);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468 if (key == NULL)
469 return NULL;
470
471 if (PyDict_DelItem(self->dict, key) == -1) {
472 Py_DECREF(key);
473 /* This will simply raise the KeyError set by PyDict_DelItem
474 if the file descriptor isn't registered. */
475 return NULL;
476 }
477
478 Py_DECREF(key);
479 self->ufd_uptodate = 0;
480
481 Py_INCREF(Py_None);
482 return Py_None;
483}
484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
487Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000488any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489
490static PyObject *
491poll_poll(pollObject *self, PyObject *args)
492{
493 PyObject *result_list = NULL, *tout = NULL;
494 int timeout = 0, poll_result, i, j;
495 PyObject *value = NULL, *num = NULL;
496
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000497 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498 return NULL;
499 }
500
501 /* Check values for timeout */
502 if (tout == NULL || tout == Py_None)
503 timeout = -1;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000504 else if (!PyNumber_Check(tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000505 PyErr_SetString(PyExc_TypeError,
506 "timeout must be an integer or None");
507 return NULL;
508 }
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000509 else {
Mark Dickinson17c7cd82009-01-17 21:57:11 +0000510 tout = PyNumber_Long(tout);
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000511 if (!tout)
512 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +0000513 timeout = PyLong_AsLong(tout);
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000514 Py_DECREF(tout);
Neal Norwitz0f46bbf2005-11-03 05:00:25 +0000515 if (timeout == -1 && PyErr_Occurred())
516 return NULL;
Neal Norwitz77c72bb2002-07-28 15:12:10 +0000517 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518
519 /* Ensure the ufd array is up to date */
520 if (!self->ufd_uptodate)
521 if (update_ufd_array(self) == 0)
522 return NULL;
523
524 /* call poll() */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000525 Py_BEGIN_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000526 poll_result = poll(self->ufds, self->ufd_len, timeout);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000527 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000528
529 if (poll_result < 0) {
530 PyErr_SetFromErrno(SelectError);
531 return NULL;
532 }
533
534 /* build the result list */
535
536 result_list = PyList_New(poll_result);
537 if (!result_list)
538 return NULL;
539 else {
540 for (i = 0, j = 0; j < poll_result; j++) {
541 /* skip to the next fired descriptor */
542 while (!self->ufds[i].revents) {
543 i++;
544 }
545 /* if we hit a NULL return, set value to NULL
546 and break out of loop; code at end will
547 clean up result_list */
548 value = PyTuple_New(2);
549 if (value == NULL)
550 goto error;
Christian Heimes217cfd12007-12-02 14:31:20 +0000551 num = PyLong_FromLong(self->ufds[i].fd);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000552 if (num == NULL) {
553 Py_DECREF(value);
554 goto error;
555 }
556 PyTuple_SET_ITEM(value, 0, num);
557
Andrew M. Kuchlinge5dd1622004-08-07 17:21:27 +0000558 /* The &0xffff is a workaround for AIX. 'revents'
559 is a 16-bit short, and IBM assigned POLLNVAL
560 to be 0x8000, so the conversion to int results
561 in a negative number. See SF bug #923315. */
Christian Heimes217cfd12007-12-02 14:31:20 +0000562 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000563 if (num == NULL) {
564 Py_DECREF(value);
565 goto error;
566 }
567 PyTuple_SET_ITEM(value, 1, num);
568 if ((PyList_SetItem(result_list, j, value)) == -1) {
569 Py_DECREF(value);
570 goto error;
571 }
572 i++;
573 }
574 }
575 return result_list;
576
577 error:
578 Py_DECREF(result_list);
579 return NULL;
580}
581
582static PyMethodDef poll_methods[] = {
583 {"register", (PyCFunction)poll_register,
584 METH_VARARGS, poll_register_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000585 {"modify", (PyCFunction)poll_modify,
586 METH_VARARGS, poll_modify_doc},
587 {"unregister", (PyCFunction)poll_unregister,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000588 METH_O, poll_unregister_doc},
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589 {"poll", (PyCFunction)poll_poll,
590 METH_VARARGS, poll_poll_doc},
591 {NULL, NULL} /* sentinel */
592};
593
594static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000595newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000596{
597 pollObject *self;
598 self = PyObject_New(pollObject, &poll_Type);
599 if (self == NULL)
600 return NULL;
601 /* ufd_uptodate is a Boolean, denoting whether the
602 array pointed to by ufds matches the contents of the dictionary. */
603 self->ufd_uptodate = 0;
604 self->ufds = NULL;
605 self->dict = PyDict_New();
606 if (self->dict == NULL) {
607 Py_DECREF(self);
608 return NULL;
609 }
610 return self;
611}
612
613static void
614poll_dealloc(pollObject *self)
615{
616 if (self->ufds != NULL)
617 PyMem_DEL(self->ufds);
618 Py_XDECREF(self->dict);
619 PyObject_Del(self);
620}
621
Tim Peters0c322792002-07-17 16:49:03 +0000622static PyTypeObject poll_Type = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623 /* The ob_type field must be initialized in the module init function
624 * to be portable to Windows without using C++. */
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000625 PyVarObject_HEAD_INIT(NULL, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000626 "select.poll", /*tp_name*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000627 sizeof(pollObject), /*tp_basicsize*/
628 0, /*tp_itemsize*/
629 /* methods */
630 (destructor)poll_dealloc, /*tp_dealloc*/
631 0, /*tp_print*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000632 0, /*tp_getattr*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000633 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000634 0, /*tp_reserved*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000635 0, /*tp_repr*/
636 0, /*tp_as_number*/
637 0, /*tp_as_sequence*/
638 0, /*tp_as_mapping*/
639 0, /*tp_hash*/
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000640 0, /*tp_call*/
641 0, /*tp_str*/
642 0, /*tp_getattro*/
643 0, /*tp_setattro*/
644 0, /*tp_as_buffer*/
645 Py_TPFLAGS_DEFAULT, /*tp_flags*/
646 0, /*tp_doc*/
647 0, /*tp_traverse*/
648 0, /*tp_clear*/
649 0, /*tp_richcompare*/
650 0, /*tp_weaklistoffset*/
651 0, /*tp_iter*/
652 0, /*tp_iternext*/
653 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654};
655
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000656PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000658unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659
660static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000661select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000662{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000663 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000664}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665
666#ifdef __APPLE__
667/*
668 * On some systems poll() sets errno on invalid file descriptors. We test
669 * for this at runtime because this bug may be fixed or introduced between
670 * OS releases.
671 */
672static int select_have_broken_poll(void)
673{
674 int poll_test;
675 int filedes[2];
676
677 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
678
679 /* Create a file descriptor to make invalid */
680 if (pipe(filedes) < 0) {
681 return 1;
682 }
683 poll_struct.fd = filedes[0];
684 close(filedes[0]);
685 close(filedes[1]);
686 poll_test = poll(&poll_struct, 1, 0);
687 if (poll_test < 0) {
688 return 1;
689 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
690 return 1;
691 }
692 return 0;
693}
694#endif /* __APPLE__ */
695
696#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000697
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000698#ifdef HAVE_EPOLL
699/* **************************************************************************
700 * epoll interface for Linux 2.6
701 *
702 * Written by Christian Heimes
703 * Inspired by Twisted's _epoll.pyx and select.poll()
704 */
705
706#ifdef HAVE_SYS_EPOLL_H
707#include <sys/epoll.h>
708#endif
709
710typedef struct {
711 PyObject_HEAD
712 SOCKET epfd; /* epoll control file descriptor */
713} pyEpoll_Object;
714
715static PyTypeObject pyEpoll_Type;
716#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
717
718static PyObject *
719pyepoll_err_closed(void)
720{
721 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
722 return NULL;
723}
724
725static int
726pyepoll_internal_close(pyEpoll_Object *self)
727{
728 int save_errno = 0;
729 if (self->epfd >= 0) {
730 int epfd = self->epfd;
731 self->epfd = -1;
732 Py_BEGIN_ALLOW_THREADS
733 if (close(epfd) < 0)
734 save_errno = errno;
735 Py_END_ALLOW_THREADS
736 }
737 return save_errno;
738}
739
740static PyObject *
741newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
742{
743 pyEpoll_Object *self;
744
745 if (sizehint == -1) {
746 sizehint = FD_SETSIZE-1;
747 }
748 else if (sizehint < 1) {
749 PyErr_Format(PyExc_ValueError,
750 "sizehint must be greater zero, got %d",
751 sizehint);
752 return NULL;
753 }
754
755 assert(type != NULL && type->tp_alloc != NULL);
756 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
757 if (self == NULL)
758 return NULL;
759
760 if (fd == -1) {
761 Py_BEGIN_ALLOW_THREADS
762 self->epfd = epoll_create(sizehint);
763 Py_END_ALLOW_THREADS
764 }
765 else {
766 self->epfd = fd;
767 }
768 if (self->epfd < 0) {
769 Py_DECREF(self);
770 PyErr_SetFromErrno(PyExc_IOError);
771 return NULL;
772 }
773 return (PyObject *)self;
774}
775
776
777static PyObject *
778pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
779{
780 int sizehint = -1;
781 static char *kwlist[] = {"sizehint", NULL};
782
783 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
784 &sizehint))
785 return NULL;
786
787 return newPyEpoll_Object(type, sizehint, -1);
788}
789
790
791static void
792pyepoll_dealloc(pyEpoll_Object *self)
793{
794 (void)pyepoll_internal_close(self);
795 Py_TYPE(self)->tp_free(self);
796}
797
798static PyObject*
799pyepoll_close(pyEpoll_Object *self)
800{
801 errno = pyepoll_internal_close(self);
802 if (errno < 0) {
803 PyErr_SetFromErrno(PyExc_IOError);
804 return NULL;
805 }
806 Py_RETURN_NONE;
807}
808
809PyDoc_STRVAR(pyepoll_close_doc,
810"close() -> None\n\
811\n\
812Close the epoll control file descriptor. Further operations on the epoll\n\
813object will raise an exception.");
814
815static PyObject*
816pyepoll_get_closed(pyEpoll_Object *self)
817{
818 if (self->epfd < 0)
819 Py_RETURN_TRUE;
820 else
821 Py_RETURN_FALSE;
822}
823
824static PyObject*
825pyepoll_fileno(pyEpoll_Object *self)
826{
827 if (self->epfd < 0)
828 return pyepoll_err_closed();
829 return PyLong_FromLong(self->epfd);
830}
831
832PyDoc_STRVAR(pyepoll_fileno_doc,
833"fileno() -> int\n\
834\n\
835Return the epoll control file descriptor.");
836
837static PyObject*
838pyepoll_fromfd(PyObject *cls, PyObject *args)
839{
840 SOCKET fd;
841
842 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
843 return NULL;
844
845 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
846}
847
848PyDoc_STRVAR(pyepoll_fromfd_doc,
849"fromfd(fd) -> epoll\n\
850\n\
851Create an epoll object from a given control fd.");
852
853static PyObject *
854pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
855{
856 struct epoll_event ev;
857 int result;
858 int fd;
859
860 if (epfd < 0)
861 return pyepoll_err_closed();
862
863 fd = PyObject_AsFileDescriptor(pfd);
864 if (fd == -1) {
865 return NULL;
866 }
867
868 switch(op) {
869 case EPOLL_CTL_ADD:
870 case EPOLL_CTL_MOD:
871 ev.events = events;
872 ev.data.fd = fd;
873 Py_BEGIN_ALLOW_THREADS
874 result = epoll_ctl(epfd, op, fd, &ev);
875 Py_END_ALLOW_THREADS
876 break;
877 case EPOLL_CTL_DEL:
878 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
879 * operation required a non-NULL pointer in event, even
880 * though this argument is ignored. */
881 Py_BEGIN_ALLOW_THREADS
882 result = epoll_ctl(epfd, op, fd, &ev);
883 if (errno == EBADF) {
884 /* fd already closed */
885 result = 0;
886 errno = 0;
887 }
888 Py_END_ALLOW_THREADS
889 break;
890 default:
891 result = -1;
892 errno = EINVAL;
893 }
894
895 if (result < 0) {
896 PyErr_SetFromErrno(PyExc_IOError);
897 return NULL;
898 }
899 Py_RETURN_NONE;
900}
901
902static PyObject *
903pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
904{
905 PyObject *pfd;
906 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
907 static char *kwlist[] = {"fd", "eventmask", NULL};
908
909 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
910 &pfd, &events)) {
911 return NULL;
912 }
913
914 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
915}
916
917PyDoc_STRVAR(pyepoll_register_doc,
918"register(fd[, eventmask]) -> bool\n\
919\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000920Registers a new fd or modifies an already registered fd. register() returns\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000921True if a new fd was registered or False if the event mask for fd was modified.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000922fd is the target file descriptor of the operation.\n\
923events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000924is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
925\n\
926The epoll interface supports all file descriptors that support poll.");
927
928static PyObject *
929pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
930{
931 PyObject *pfd;
932 unsigned int events;
933 static char *kwlist[] = {"fd", "eventmask", NULL};
934
935 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
936 &pfd, &events)) {
937 return NULL;
938 }
939
940 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
941}
942
943PyDoc_STRVAR(pyepoll_modify_doc,
944"modify(fd, eventmask) -> None\n\
945\n\
946fd is the target file descriptor of the operation\n\
947events is a bit set composed of the various EPOLL constants");
948
949static PyObject *
950pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
951{
952 PyObject *pfd;
953 static char *kwlist[] = {"fd", NULL};
954
955 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
956 &pfd)) {
957 return NULL;
958 }
959
960 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
961}
962
963PyDoc_STRVAR(pyepoll_unregister_doc,
964"unregister(fd) -> None\n\
965\n\
966fd is the target file descriptor of the operation.");
967
968static PyObject *
969pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
970{
971 double dtimeout = -1.;
972 int timeout;
973 int maxevents = -1;
974 int nfds, i;
975 PyObject *elist = NULL, *etuple = NULL;
976 struct epoll_event *evs = NULL;
977 static char *kwlist[] = {"timeout", "maxevents", NULL};
978
979 if (self->epfd < 0)
980 return pyepoll_err_closed();
981
982 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
983 &dtimeout, &maxevents)) {
984 return NULL;
985 }
986
987 if (dtimeout < 0) {
988 timeout = -1;
989 }
990 else if (dtimeout * 1000.0 > INT_MAX) {
991 PyErr_SetString(PyExc_OverflowError,
992 "timeout is too large");
Christian Heimesf6cd9672008-03-26 13:45:42 +0000993 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000994 }
995 else {
996 timeout = (int)(dtimeout * 1000.0);
997 }
998
999 if (maxevents == -1) {
1000 maxevents = FD_SETSIZE-1;
1001 }
1002 else if (maxevents < 1) {
1003 PyErr_Format(PyExc_ValueError,
1004 "maxevents must be greater than 0, got %d",
1005 maxevents);
1006 return NULL;
1007 }
1008
1009 evs = PyMem_New(struct epoll_event, maxevents);
1010 if (evs == NULL) {
1011 Py_DECREF(self);
1012 PyErr_NoMemory();
1013 return NULL;
1014 }
1015
1016 Py_BEGIN_ALLOW_THREADS
1017 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1018 Py_END_ALLOW_THREADS
1019 if (nfds < 0) {
1020 PyErr_SetFromErrno(PyExc_IOError);
1021 goto error;
1022 }
1023
1024 elist = PyList_New(nfds);
1025 if (elist == NULL) {
1026 goto error;
1027 }
1028
1029 for (i = 0; i < nfds; i++) {
Christian Heimesf6cd9672008-03-26 13:45:42 +00001030 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001031 if (etuple == NULL) {
Christian Heimesf6cd9672008-03-26 13:45:42 +00001032 Py_CLEAR(elist);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001033 goto error;
1034 }
1035 PyList_SET_ITEM(elist, i, etuple);
1036 }
1037
Christian Heimesf6cd9672008-03-26 13:45:42 +00001038 error:
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001039 PyMem_Free(evs);
1040 return elist;
1041}
1042
1043PyDoc_STRVAR(pyepoll_poll_doc,
1044"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1045\n\
1046Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1047in seconds (as float). -1 makes poll wait indefinitely.\n\
1048Up to maxevents are returned to the caller.");
1049
1050static PyMethodDef pyepoll_methods[] = {
1051 {"fromfd", (PyCFunction)pyepoll_fromfd,
1052 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1053 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1054 pyepoll_close_doc},
1055 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1056 pyepoll_fileno_doc},
1057 {"modify", (PyCFunction)pyepoll_modify,
1058 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1059 {"register", (PyCFunction)pyepoll_register,
1060 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1061 {"unregister", (PyCFunction)pyepoll_unregister,
1062 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1063 {"poll", (PyCFunction)pyepoll_poll,
1064 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1065 {NULL, NULL},
1066};
1067
1068static PyGetSetDef pyepoll_getsetlist[] = {
1069 {"closed", (getter)pyepoll_get_closed, NULL,
1070 "True if the epoll handler is closed"},
1071 {0},
1072};
1073
1074PyDoc_STRVAR(pyepoll_doc,
1075"select.epoll([sizehint=-1])\n\
1076\n\
1077Returns an epolling object\n\
1078\n\
1079sizehint must be a positive integer or -1 for the default size. The\n\
1080sizehint is used to optimize internal data structures. It doesn't limit\n\
1081the maximum number of monitored events.");
1082
1083static PyTypeObject pyEpoll_Type = {
1084 PyVarObject_HEAD_INIT(NULL, 0)
1085 "select.epoll", /* tp_name */
1086 sizeof(pyEpoll_Object), /* tp_basicsize */
1087 0, /* tp_itemsize */
1088 (destructor)pyepoll_dealloc, /* tp_dealloc */
1089 0, /* tp_print */
1090 0, /* tp_getattr */
1091 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00001092 0, /* tp_reserved */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001093 0, /* tp_repr */
1094 0, /* tp_as_number */
1095 0, /* tp_as_sequence */
1096 0, /* tp_as_mapping */
1097 0, /* tp_hash */
1098 0, /* tp_call */
1099 0, /* tp_str */
1100 PyObject_GenericGetAttr, /* tp_getattro */
1101 0, /* tp_setattro */
1102 0, /* tp_as_buffer */
1103 Py_TPFLAGS_DEFAULT, /* tp_flags */
1104 pyepoll_doc, /* tp_doc */
1105 0, /* tp_traverse */
1106 0, /* tp_clear */
1107 0, /* tp_richcompare */
1108 0, /* tp_weaklistoffset */
1109 0, /* tp_iter */
1110 0, /* tp_iternext */
1111 pyepoll_methods, /* tp_methods */
1112 0, /* tp_members */
1113 pyepoll_getsetlist, /* tp_getset */
1114 0, /* tp_base */
1115 0, /* tp_dict */
1116 0, /* tp_descr_get */
1117 0, /* tp_descr_set */
1118 0, /* tp_dictoffset */
1119 0, /* tp_init */
1120 0, /* tp_alloc */
1121 pyepoll_new, /* tp_new */
1122 0, /* tp_free */
1123};
1124
1125#endif /* HAVE_EPOLL */
1126
1127#ifdef HAVE_KQUEUE
1128/* **************************************************************************
1129 * kqueue interface for BSD
1130 *
1131 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1132 * All rights reserved.
1133 *
1134 * Redistribution and use in source and binary forms, with or without
1135 * modification, are permitted provided that the following conditions
1136 * are met:
1137 * 1. Redistributions of source code must retain the above copyright
1138 * notice, this list of conditions and the following disclaimer.
1139 * 2. Redistributions in binary form must reproduce the above copyright
1140 * notice, this list of conditions and the following disclaimer in the
1141 * documentation and/or other materials provided with the distribution.
1142 *
1143 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1144 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1145 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1146 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1147 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1148 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1149 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1150 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1151 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1152 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1153 * SUCH DAMAGE.
1154 */
1155
1156#ifdef HAVE_SYS_EVENT_H
1157#include <sys/event.h>
1158#endif
1159
1160PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001161"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001162\n\
1163This object is the equivalent of the struct kevent for the C API.\n\
1164\n\
1165See the kqueue manpage for more detailed information about the meaning\n\
1166of the arguments.\n\
1167\n\
1168One minor note: while you might hope that udata could store a\n\
1169reference to a python object, it cannot, because it is impossible to\n\
1170keep a proper reference count of the object once it's passed into the\n\
1171kernel. Therefore, I have restricted it to only storing an integer. I\n\
1172recommend ignoring it and simply using the 'ident' field to key off\n\
1173of. You could also set up a dictionary on the python side to store a\n\
1174udata->object mapping.");
1175
1176typedef struct {
1177 PyObject_HEAD
1178 struct kevent e;
1179} kqueue_event_Object;
1180
1181static PyTypeObject kqueue_event_Type;
1182
1183#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1184
1185typedef struct {
1186 PyObject_HEAD
1187 SOCKET kqfd; /* kqueue control fd */
1188} kqueue_queue_Object;
1189
1190static PyTypeObject kqueue_queue_Type;
1191
1192#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1193
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001194#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1195# error uintptr_t does not match void *!
1196#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1197# define T_UINTPTRT T_ULONGLONG
1198# define T_INTPTRT T_LONGLONG
1199# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1200# define UINTPTRT_FMT_UNIT "K"
1201# define INTPTRT_FMT_UNIT "L"
1202#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1203# define T_UINTPTRT T_ULONG
1204# define T_INTPTRT T_LONG
1205# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1206# define UINTPTRT_FMT_UNIT "k"
1207# define INTPTRT_FMT_UNIT "l"
1208#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1209# define T_UINTPTRT T_UINT
1210# define T_INTPTRT T_INT
1211# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1212# define UINTPTRT_FMT_UNIT "I"
1213# define INTPTRT_FMT_UNIT "i"
1214#else
1215# error uintptr_t does not match int, long, or long long!
1216#endif
1217
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001218/* Unfortunately, we can't store python objects in udata, because
1219 * kevents in the kernel can be removed without warning, which would
1220 * forever lose the refcount on the object stored with it.
1221 */
1222
1223#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1224static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001225 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001226 {"filter", T_SHORT, KQ_OFF(e.filter)},
1227 {"flags", T_USHORT, KQ_OFF(e.flags)},
1228 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001229 {"data", T_INTPTRT, KQ_OFF(e.data)},
1230 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231 {NULL} /* Sentinel */
1232};
1233#undef KQ_OFF
1234
1235static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001236
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001237kqueue_event_repr(kqueue_event_Object *s)
1238{
1239 char buf[1024];
1240 PyOS_snprintf(
1241 buf, sizeof(buf),
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001242 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1243 "data=0x%zd udata=%p>",
1244 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1245 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1246 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001247}
1248
1249static int
1250kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1251{
1252 PyObject *pfd;
1253 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1254 "data", "udata", NULL};
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001255 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256
1257 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1258
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001259 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260 &pfd, &(self->e.filter), &(self->e.flags),
1261 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1262 return -1;
1263 }
1264
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001265 if (PyLong_Check(pfd)) {
1266 self->e.ident = PyLong_AsUintptr_t(pfd);
1267 }
1268 else {
1269 self->e.ident = PyObject_AsFileDescriptor(pfd);
1270 }
1271 if (PyErr_Occurred()) {
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001272 return -1;
1273 }
1274 return 0;
1275}
1276
1277static PyObject *
1278kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1279 int op)
1280{
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001281 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001282
1283 if (!kqueue_event_Check(o)) {
1284 if (op == Py_EQ || op == Py_NE) {
1285 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1286 Py_INCREF(res);
1287 return res;
1288 }
1289 PyErr_Format(PyExc_TypeError,
1290 "can't compare %.200s to %.200s",
1291 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1292 return NULL;
1293 }
1294 if (((result = s->e.ident - o->e.ident) == 0) &&
1295 ((result = s->e.filter - o->e.filter) == 0) &&
1296 ((result = s->e.flags - o->e.flags) == 0) &&
1297 ((result = s->e.fflags - o->e.fflags) == 0) &&
1298 ((result = s->e.data - o->e.data) == 0) &&
1299 ((result = s->e.udata - o->e.udata) == 0)
1300 ) {
1301 result = 0;
1302 }
1303
1304 switch (op) {
1305 case Py_EQ:
1306 result = (result == 0);
1307 break;
1308 case Py_NE:
1309 result = (result != 0);
1310 break;
1311 case Py_LE:
1312 result = (result <= 0);
1313 break;
1314 case Py_GE:
1315 result = (result >= 0);
1316 break;
1317 case Py_LT:
1318 result = (result < 0);
1319 break;
1320 case Py_GT:
1321 result = (result > 0);
1322 break;
1323 }
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001324 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001325}
1326
1327static PyTypeObject kqueue_event_Type = {
1328 PyVarObject_HEAD_INIT(NULL, 0)
1329 "select.kevent", /* tp_name */
1330 sizeof(kqueue_event_Object), /* tp_basicsize */
1331 0, /* tp_itemsize */
1332 0, /* tp_dealloc */
1333 0, /* tp_print */
1334 0, /* tp_getattr */
1335 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00001336 0, /* tp_reserved */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001337 (reprfunc)kqueue_event_repr, /* tp_repr */
1338 0, /* tp_as_number */
1339 0, /* tp_as_sequence */
1340 0, /* tp_as_mapping */
1341 0, /* tp_hash */
1342 0, /* tp_call */
1343 0, /* tp_str */
1344 0, /* tp_getattro */
1345 0, /* tp_setattro */
1346 0, /* tp_as_buffer */
1347 Py_TPFLAGS_DEFAULT, /* tp_flags */
1348 kqueue_event_doc, /* tp_doc */
1349 0, /* tp_traverse */
1350 0, /* tp_clear */
1351 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1352 0, /* tp_weaklistoffset */
1353 0, /* tp_iter */
1354 0, /* tp_iternext */
1355 0, /* tp_methods */
1356 kqueue_event_members, /* tp_members */
1357 0, /* tp_getset */
1358 0, /* tp_base */
1359 0, /* tp_dict */
1360 0, /* tp_descr_get */
1361 0, /* tp_descr_set */
1362 0, /* tp_dictoffset */
1363 (initproc)kqueue_event_init, /* tp_init */
1364 0, /* tp_alloc */
1365 0, /* tp_new */
1366 0, /* tp_free */
1367};
1368
1369static PyObject *
1370kqueue_queue_err_closed(void)
1371{
1372 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1373 return NULL;
1374}
1375
1376static int
1377kqueue_queue_internal_close(kqueue_queue_Object *self)
1378{
1379 int save_errno = 0;
1380 if (self->kqfd >= 0) {
1381 int kqfd = self->kqfd;
1382 self->kqfd = -1;
1383 Py_BEGIN_ALLOW_THREADS
1384 if (close(kqfd) < 0)
1385 save_errno = errno;
1386 Py_END_ALLOW_THREADS
1387 }
1388 return save_errno;
1389}
1390
1391static PyObject *
1392newKqueue_Object(PyTypeObject *type, SOCKET fd)
1393{
1394 kqueue_queue_Object *self;
1395 assert(type != NULL && type->tp_alloc != NULL);
1396 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1397 if (self == NULL) {
1398 return NULL;
1399 }
1400
1401 if (fd == -1) {
1402 Py_BEGIN_ALLOW_THREADS
1403 self->kqfd = kqueue();
1404 Py_END_ALLOW_THREADS
1405 }
1406 else {
1407 self->kqfd = fd;
1408 }
1409 if (self->kqfd < 0) {
1410 Py_DECREF(self);
1411 PyErr_SetFromErrno(PyExc_IOError);
1412 return NULL;
1413 }
1414 return (PyObject *)self;
1415}
1416
1417static PyObject *
1418kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1419{
1420
1421 if ((args != NULL && PyObject_Size(args)) ||
1422 (kwds != NULL && PyObject_Size(kwds))) {
1423 PyErr_SetString(PyExc_ValueError,
1424 "select.kqueue doesn't accept arguments");
1425 return NULL;
1426 }
1427
1428 return newKqueue_Object(type, -1);
1429}
1430
1431static void
1432kqueue_queue_dealloc(kqueue_queue_Object *self)
1433{
1434 kqueue_queue_internal_close(self);
1435 Py_TYPE(self)->tp_free(self);
1436}
1437
1438static PyObject*
1439kqueue_queue_close(kqueue_queue_Object *self)
1440{
1441 errno = kqueue_queue_internal_close(self);
1442 if (errno < 0) {
1443 PyErr_SetFromErrno(PyExc_IOError);
1444 return NULL;
1445 }
1446 Py_RETURN_NONE;
1447}
1448
1449PyDoc_STRVAR(kqueue_queue_close_doc,
1450"close() -> None\n\
1451\n\
1452Close the kqueue control file descriptor. Further operations on the kqueue\n\
1453object will raise an exception.");
1454
1455static PyObject*
1456kqueue_queue_get_closed(kqueue_queue_Object *self)
1457{
1458 if (self->kqfd < 0)
1459 Py_RETURN_TRUE;
1460 else
1461 Py_RETURN_FALSE;
1462}
1463
1464static PyObject*
1465kqueue_queue_fileno(kqueue_queue_Object *self)
1466{
1467 if (self->kqfd < 0)
1468 return kqueue_queue_err_closed();
1469 return PyLong_FromLong(self->kqfd);
1470}
1471
1472PyDoc_STRVAR(kqueue_queue_fileno_doc,
1473"fileno() -> int\n\
1474\n\
1475Return the kqueue control file descriptor.");
1476
1477static PyObject*
1478kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1479{
1480 SOCKET fd;
1481
1482 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1483 return NULL;
1484
1485 return newKqueue_Object((PyTypeObject*)cls, fd);
1486}
1487
1488PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1489"fromfd(fd) -> kqueue\n\
1490\n\
1491Create a kqueue object from a given control fd.");
1492
1493static PyObject *
1494kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1495{
1496 int nevents = 0;
1497 int gotevents = 0;
1498 int nchanges = 0;
1499 int i = 0;
1500 PyObject *otimeout = NULL;
1501 PyObject *ch = NULL;
1502 PyObject *it = NULL, *ei = NULL;
1503 PyObject *result = NULL;
1504 struct kevent *evl = NULL;
1505 struct kevent *chl = NULL;
1506 struct timespec timeoutspec;
1507 struct timespec *ptimeoutspec;
1508
1509 if (self->kqfd < 0)
1510 return kqueue_queue_err_closed();
1511
1512 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1513 return NULL;
1514
1515 if (nevents < 0) {
1516 PyErr_Format(PyExc_ValueError,
1517 "Length of eventlist must be 0 or positive, got %d",
Alexandre Vassalottie52e3782009-07-17 09:18:18 +00001518 nevents);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001519 return NULL;
1520 }
1521
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001522 if (otimeout == Py_None || otimeout == NULL) {
1523 ptimeoutspec = NULL;
1524 }
1525 else if (PyNumber_Check(otimeout)) {
1526 double timeout;
1527 long seconds;
1528
1529 timeout = PyFloat_AsDouble(otimeout);
1530 if (timeout == -1 && PyErr_Occurred())
1531 return NULL;
1532 if (timeout > (double)LONG_MAX) {
1533 PyErr_SetString(PyExc_OverflowError,
1534 "timeout period too long");
1535 return NULL;
1536 }
1537 if (timeout < 0) {
1538 PyErr_SetString(PyExc_ValueError,
1539 "timeout must be positive or None");
1540 return NULL;
1541 }
1542
1543 seconds = (long)timeout;
1544 timeout = timeout - (double)seconds;
1545 timeoutspec.tv_sec = seconds;
1546 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1547 ptimeoutspec = &timeoutspec;
1548 }
1549 else {
1550 PyErr_Format(PyExc_TypeError,
1551 "timeout argument must be an number "
1552 "or None, got %.200s",
1553 Py_TYPE(otimeout)->tp_name);
1554 return NULL;
1555 }
1556
Georg Brandlc0e22b72010-03-14 10:51:01 +00001557 if (ch != NULL && ch != Py_None) {
1558 it = PyObject_GetIter(ch);
1559 if (it == NULL) {
1560 PyErr_SetString(PyExc_TypeError,
1561 "changelist is not iterable");
1562 return NULL;
1563 }
1564 nchanges = PyObject_Size(ch);
1565 if (nchanges < 0) {
1566 goto error;
1567 }
1568
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001569 chl = PyMem_New(struct kevent, nchanges);
1570 if (chl == NULL) {
1571 PyErr_NoMemory();
Georg Brandlc0e22b72010-03-14 10:51:01 +00001572 goto error;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001573 }
Alexandre Vassalottie52e3782009-07-17 09:18:18 +00001574 i = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001575 while ((ei = PyIter_Next(it)) != NULL) {
1576 if (!kqueue_event_Check(ei)) {
1577 Py_DECREF(ei);
1578 PyErr_SetString(PyExc_TypeError,
1579 "changelist must be an iterable of "
1580 "select.kevent objects");
1581 goto error;
1582 } else {
Alexandre Vassalottie52e3782009-07-17 09:18:18 +00001583 chl[i++] = ((kqueue_event_Object *)ei)->e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001584 }
1585 Py_DECREF(ei);
1586 }
1587 }
1588 Py_CLEAR(it);
1589
1590 /* event list */
1591 if (nevents) {
1592 evl = PyMem_New(struct kevent, nevents);
1593 if (evl == NULL) {
1594 PyErr_NoMemory();
Georg Brandlc0e22b72010-03-14 10:51:01 +00001595 goto error;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596 }
1597 }
1598
1599 Py_BEGIN_ALLOW_THREADS
1600 gotevents = kevent(self->kqfd, chl, nchanges,
1601 evl, nevents, ptimeoutspec);
1602 Py_END_ALLOW_THREADS
1603
1604 if (gotevents == -1) {
1605 PyErr_SetFromErrno(PyExc_OSError);
1606 goto error;
1607 }
1608
1609 result = PyList_New(gotevents);
1610 if (result == NULL) {
1611 goto error;
1612 }
1613
Alexandre Vassalottie52e3782009-07-17 09:18:18 +00001614 for (i = 0; i < gotevents; i++) {
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001615 kqueue_event_Object *ch;
1616
1617 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1618 if (ch == NULL) {
1619 goto error;
1620 }
1621 ch->e = evl[i];
1622 PyList_SET_ITEM(result, i, (PyObject *)ch);
1623 }
1624 PyMem_Free(chl);
1625 PyMem_Free(evl);
1626 return result;
1627
1628 error:
1629 PyMem_Free(chl);
1630 PyMem_Free(evl);
1631 Py_XDECREF(result);
1632 Py_XDECREF(it);
1633 return NULL;
1634}
1635
1636PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001637"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001638\n\
1639Calls the kernel kevent function.\n\
1640- changelist must be a list of kevent objects describing the changes\n\
1641 to be made to the kernel's watch list or None.\n\
1642- max_events lets you specify the maximum number of events that the\n\
1643 kernel will return.\n\
1644- timeout is the maximum time to wait in seconds, or else None,\n\
1645 to wait forever. timeout accepts floats for smaller timeouts, too.");
1646
1647
1648static PyMethodDef kqueue_queue_methods[] = {
1649 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1650 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1651 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1652 kqueue_queue_close_doc},
1653 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1654 kqueue_queue_fileno_doc},
1655 {"control", (PyCFunction)kqueue_queue_control,
1656 METH_VARARGS , kqueue_queue_control_doc},
1657 {NULL, NULL},
1658};
1659
1660static PyGetSetDef kqueue_queue_getsetlist[] = {
1661 {"closed", (getter)kqueue_queue_get_closed, NULL,
1662 "True if the kqueue handler is closed"},
1663 {0},
1664};
1665
1666PyDoc_STRVAR(kqueue_queue_doc,
1667"Kqueue syscall wrapper.\n\
1668\n\
1669For example, to start watching a socket for input:\n\
1670>>> kq = kqueue()\n\
1671>>> sock = socket()\n\
1672>>> sock.connect((host, port))\n\
1673>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1674\n\
1675To wait one second for it to become writeable:\n\
1676>>> kq.control(None, 1, 1000)\n\
1677\n\
1678To stop listening:\n\
1679>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1680
1681static PyTypeObject kqueue_queue_Type = {
1682 PyVarObject_HEAD_INIT(NULL, 0)
1683 "select.kqueue", /* tp_name */
1684 sizeof(kqueue_queue_Object), /* tp_basicsize */
1685 0, /* tp_itemsize */
1686 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1687 0, /* tp_print */
1688 0, /* tp_getattr */
1689 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00001690 0, /* tp_reserved */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001691 0, /* tp_repr */
1692 0, /* tp_as_number */
1693 0, /* tp_as_sequence */
1694 0, /* tp_as_mapping */
1695 0, /* tp_hash */
1696 0, /* tp_call */
1697 0, /* tp_str */
1698 0, /* tp_getattro */
1699 0, /* tp_setattro */
1700 0, /* tp_as_buffer */
1701 Py_TPFLAGS_DEFAULT, /* tp_flags */
1702 kqueue_queue_doc, /* tp_doc */
1703 0, /* tp_traverse */
1704 0, /* tp_clear */
1705 0, /* tp_richcompare */
1706 0, /* tp_weaklistoffset */
1707 0, /* tp_iter */
1708 0, /* tp_iternext */
1709 kqueue_queue_methods, /* tp_methods */
1710 0, /* tp_members */
1711 kqueue_queue_getsetlist, /* tp_getset */
1712 0, /* tp_base */
1713 0, /* tp_dict */
1714 0, /* tp_descr_get */
1715 0, /* tp_descr_set */
1716 0, /* tp_dictoffset */
1717 0, /* tp_init */
1718 0, /* tp_alloc */
1719 kqueue_queue_new, /* tp_new */
1720 0, /* tp_free */
1721};
1722
1723#endif /* HAVE_KQUEUE */
1724/* ************************************************************************ */
1725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001726PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001727"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1728\n\
1729Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001730The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001731rlist -- wait until ready for reading\n\
1732wlist -- wait until ready for writing\n\
1733xlist -- wait for an ``exceptional condition''\n\
1734If only one kind of condition is required, pass [] for the other lists.\n\
1735A file descriptor is either a socket or file object, or a small integer\n\
1736gotten from a fileno() method call on one of those.\n\
1737\n\
1738The optional 4th argument specifies a timeout in seconds; it may be\n\
1739a floating point number to specify fractions of seconds. If it is absent\n\
1740or None, the call will never time out.\n\
1741\n\
1742The return value is a tuple of three lists corresponding to the first three\n\
1743arguments; each contains the subset of the corresponding file descriptors\n\
1744that are ready.\n\
1745\n\
1746*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001747On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001748descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001749
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001750static PyMethodDef select_methods[] = {
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001751 {"select", select_select, METH_VARARGS, select_doc},
1752#ifdef HAVE_POLL
1753 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001754#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001755 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001756};
1757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001758PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001759"This module supports asynchronous I/O on multiple file descriptors.\n\
1760\n\
1761*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001762On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001763
Martin v. Löwis1a214512008-06-11 05:26:20 +00001764
1765static struct PyModuleDef selectmodule = {
1766 PyModuleDef_HEAD_INIT,
1767 "select",
1768 module_doc,
1769 -1,
1770 select_methods,
1771 NULL,
1772 NULL,
1773 NULL,
1774 NULL
1775};
1776
Mark Hammond62b1ab12002-07-23 06:31:15 +00001777PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001778PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001779{
Fred Drake4baedc12002-04-01 14:53:37 +00001780 PyObject *m;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001781 m = PyModule_Create(&selectmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001782 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001783 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001784
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001785 SelectError = PyErr_NewException("select.error", NULL, NULL);
Fred Drake4baedc12002-04-01 14:53:37 +00001786 Py_INCREF(SelectError);
1787 PyModule_AddObject(m, "error", SelectError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001788
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001789#ifdef PIPE_BUF
Gregory P. Smithb970b862009-07-04 02:28:47 +00001790 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001791#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001792
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001793#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794#ifdef __APPLE__
1795 if (select_have_broken_poll()) {
1796 if (PyObject_DelAttrString(m, "poll") == -1) {
1797 PyErr_Clear();
1798 }
1799 } else {
1800#else
1801 {
1802#endif
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00001803 if (PyType_Ready(&poll_Type) < 0)
1804 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001805 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1806 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1807 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1808 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1809 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1810 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001811
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001812#ifdef POLLRDNORM
Thomas Wouters477c8d52006-05-27 19:21:47 +00001813 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001814#endif
1815#ifdef POLLRDBAND
Thomas Wouters477c8d52006-05-27 19:21:47 +00001816 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001817#endif
1818#ifdef POLLWRNORM
Thomas Wouters477c8d52006-05-27 19:21:47 +00001819 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001820#endif
1821#ifdef POLLWRBAND
Thomas Wouters477c8d52006-05-27 19:21:47 +00001822 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001823#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001824#ifdef POLLMSG
Thomas Wouters477c8d52006-05-27 19:21:47 +00001825 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001826#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827 }
1828#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001829
1830#ifdef HAVE_EPOLL
1831 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1832 if (PyType_Ready(&pyEpoll_Type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001833 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001834
1835 Py_INCREF(&pyEpoll_Type);
1836 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
1837
1838 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1839 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1840 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1841 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1842 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1843 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
1844#ifdef EPOLLONESHOT
1845 /* Kernel 2.6.2+ */
1846 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
1847#endif
1848 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1849 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1850 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1851 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1852 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1853 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
1854#endif /* HAVE_EPOLL */
1855
1856#ifdef HAVE_KQUEUE
1857 kqueue_event_Type.tp_new = PyType_GenericNew;
1858 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1859 if(PyType_Ready(&kqueue_event_Type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001860 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861
1862 Py_INCREF(&kqueue_event_Type);
1863 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
1864
1865 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1866 if(PyType_Ready(&kqueue_queue_Type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001867 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868 Py_INCREF(&kqueue_queue_Type);
1869 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1870
1871 /* event filters */
1872 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1873 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1874 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1875 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1876 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
1877#ifdef EVFILT_NETDEV
1878 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
1879#endif
1880 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1881 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
1882
1883 /* event flags */
1884 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1885 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1886 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1887 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1888 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1889 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
1890
1891 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1892 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
1893
1894 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1895 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
1896
1897 /* READ WRITE filter flag */
1898 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
1899
1900 /* VNODE filter flags */
1901 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1903 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1905 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1906 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1907 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
1908
1909 /* PROC filter flags */
1910 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1912 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1913 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
1915
1916 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1917 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1918 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1919
1920 /* NETDEV filter flags */
1921#ifdef EVFILT_NETDEV
1922 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1923 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1924 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
1925#endif
1926
1927#endif /* HAVE_KQUEUE */
Martin v. Löwis1a214512008-06-11 05:26:20 +00001928 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001929}