blob: 6071144cac30af6d582caec84cd40419daef4312 [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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000026
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 Warsawc1cb3601996-12-12 22:16:21 +000057/* list of Python objects and their file descriptor */
58typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 PyObject *obj; /* owned reference */
60 SOCKET fd;
61 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000062} pylist;
63
Barry Warsawc1cb3601996-12-12 22:16:21 +000064static void
Tim Peters4b046c22001-08-16 21:59:46 +000065reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 int i;
68 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
69 Py_XDECREF(fd2obj[i].obj);
70 fd2obj[i].obj = NULL;
71 }
72 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000073}
74
75
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000076/* returns -1 and sets the Python exception if an error occurred, otherwise
77 returns a number >= 0
78*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000079static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000080seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 int max = -1;
83 int index = 0;
Victor Stinner0fcab4a2011-01-04 12:59:15 +000084 Py_ssize_t i, len = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 PyObject* fast_seq = NULL;
86 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
89 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000090
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000091 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 if (!fast_seq)
93 return -1;
94
95 len = PySequence_Fast_GET_SIZE(fast_seq);
96
97 for (i = 0; i < len; i++) {
98 SOCKET v;
99
100 /* any intervening fileno() calls could decr this refcnt */
101 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000102 return -1;
103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 Py_INCREF(o);
105 v = PyObject_AsFileDescriptor( o );
106 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000108#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200111 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 PyErr_SetString(PyExc_ValueError,
113 "filedescriptor out of range in select()");
114 goto finally;
115 }
116 if (v > max)
117 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 /* add object and its file descriptor to the list */
122 if (index >= FD_SETSIZE) {
123 PyErr_SetString(PyExc_ValueError,
124 "too many file descriptors in select()");
125 goto finally;
126 }
127 fd2obj[index].obj = o;
128 fd2obj[index].fd = v;
129 fd2obj[index].sentinel = 0;
130 fd2obj[++index].sentinel = -1;
131 }
132 Py_DECREF(fast_seq);
133 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000134
135 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 Py_XDECREF(o);
137 Py_DECREF(fast_seq);
138 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000139}
140
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000141/* returns NULL and sets the Python exception if an error occurred */
142static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000143set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 int i, j, count=0;
146 PyObject *list, *o;
147 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
150 if (FD_ISSET(fd2obj[j].fd, set))
151 count++;
152 }
153 list = PyList_New(count);
154 if (!list)
155 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 i = 0;
158 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
159 fd = fd2obj[j].fd;
160 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 o = fd2obj[j].obj;
162 fd2obj[j].obj = NULL;
163 /* transfer ownership */
164 if (PyList_SetItem(list, i, o) < 0)
165 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 i++;
168 }
169 }
170 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000171 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 Py_DECREF(list);
173 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000174}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000175
Barry Warsawb44740f2001-08-16 16:52:59 +0000176#undef SELECT_USES_HEAP
177#if FD_SETSIZE > 1024
178#define SELECT_USES_HEAP
179#endif /* FD_SETSIZE > 1024 */
180
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000181static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000182select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000183{
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000186#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 /* XXX: All this should probably be implemented as follows:
188 * - find the highest descriptor we're interested in
189 * - add one
190 * - that's the size
191 * See: Stevens, APitUE, $12.5.1
192 */
193 pylist rfd2obj[FD_SETSIZE + 1];
194 pylist wfd2obj[FD_SETSIZE + 1];
195 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000196#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 PyObject *ifdlist, *ofdlist, *efdlist;
198 PyObject *ret = NULL;
199 PyObject *tout = Py_None;
200 fd_set ifdset, ofdset, efdset;
201 double timeout;
202 struct timeval tv, *tvp;
203 long seconds;
204 int imax, omax, emax, max;
205 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* convert arguments */
208 if (!PyArg_UnpackTuple(args, "select", 3, 4,
209 &ifdlist, &ofdlist, &efdlist, &tout))
210 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 if (tout == Py_None)
213 tvp = (struct timeval *)0;
214 else if (!PyNumber_Check(tout)) {
215 PyErr_SetString(PyExc_TypeError,
216 "timeout must be a float or None");
217 return NULL;
218 }
219 else {
220 timeout = PyFloat_AsDouble(tout);
221 if (timeout == -1 && PyErr_Occurred())
222 return NULL;
223 if (timeout > (double)LONG_MAX) {
224 PyErr_SetString(PyExc_OverflowError,
225 "timeout period too long");
226 return NULL;
227 }
Antoine Pitrou131a6412011-04-09 23:49:58 +0200228 if (timeout < 0) {
229 PyErr_SetString(PyExc_ValueError,
230 "timeout must be non-negative");
231 return NULL;
232 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 seconds = (long)timeout;
234 timeout = timeout - (double)seconds;
235 tv.tv_sec = seconds;
236 tv.tv_usec = (long)(timeout * 1E6);
237 tvp = &tv;
238 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000239
Guido van Rossumed233a51992-06-23 09:07:03 +0000240
Barry Warsawb44740f2001-08-16 16:52:59 +0000241#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 /* Allocate memory for the lists */
243 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
244 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
245 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
246 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
247 if (rfd2obj) PyMem_DEL(rfd2obj);
248 if (wfd2obj) PyMem_DEL(wfd2obj);
249 if (efd2obj) PyMem_DEL(efd2obj);
250 return PyErr_NoMemory();
251 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000252#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 /* Convert sequences to fd_sets, and get maximum fd number
254 * propagates the Python exception set in seq2set()
255 */
256 rfd2obj[0].sentinel = -1;
257 wfd2obj[0].sentinel = -1;
258 efd2obj[0].sentinel = -1;
259 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
260 goto finally;
261 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
262 goto finally;
263 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
264 goto finally;
265 max = imax;
266 if (omax > max) max = omax;
267 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 Py_BEGIN_ALLOW_THREADS
270 n = select(max, &ifdset, &ofdset, &efdset, tvp);
271 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000272
Thomas Heller106f4c72002-09-24 16:51:00 +0000273#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200275 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000277#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200279 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000281#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 else {
283 /* any of these three calls can raise an exception. it's more
284 convenient to test for this after all three calls... but
285 is that acceptable?
286 */
287 ifdlist = set2list(&ifdset, rfd2obj);
288 ofdlist = set2list(&ofdset, wfd2obj);
289 efdlist = set2list(&efdset, efd2obj);
290 if (PyErr_Occurred())
291 ret = NULL;
292 else
293 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 Py_DECREF(ifdlist);
296 Py_DECREF(ofdlist);
297 Py_DECREF(efdlist);
298 }
299
Barry Warsawc1cb3601996-12-12 22:16:21 +0000300 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 reap_obj(rfd2obj);
302 reap_obj(wfd2obj);
303 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000304#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 PyMem_DEL(rfd2obj);
306 PyMem_DEL(wfd2obj);
307 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000308#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000310}
311
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000312#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000314 * poll() support
315 */
316
317typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 PyObject_HEAD
319 PyObject *dict;
320 int ufd_uptodate;
321 int ufd_len;
322 struct pollfd *ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323} pollObject;
324
Jeremy Hylton938ace62002-07-17 16:30:39 +0000325static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000328 contained within a pollObject. Return 1 on success, 0 on an error.
329*/
330
331static int
332update_ufd_array(pollObject *self)
333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 Py_ssize_t i, pos;
335 PyObject *key, *value;
336 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 self->ufd_len = PyDict_Size(self->dict);
339 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
340 if (self->ufds == NULL) {
341 self->ufds = old_ufds;
342 PyErr_NoMemory();
343 return 0;
344 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 i = pos = 0;
347 while (PyDict_Next(self->dict, &pos, &key, &value)) {
348 self->ufds[i].fd = PyLong_AsLong(key);
349 self->ufds[i].events = (short)PyLong_AsLong(value);
350 i++;
351 }
352 self->ufd_uptodate = 1;
353 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000354}
355
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000356PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000357"register(fd [, eventmask] ) -> None\n\n\
358Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000359fd -- either an integer, or an object with a fileno() method returning an\n\
360 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000361events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362
363static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 PyObject *o, *key, *value;
367 int fd, events = POLLIN | POLLPRI | POLLOUT;
368 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
371 return NULL;
372 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 fd = PyObject_AsFileDescriptor(o);
375 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 /* Add entry to the internal dictionary: the key is the
378 file descriptor, and the value is the event mask. */
379 key = PyLong_FromLong(fd);
380 if (key == NULL)
381 return NULL;
382 value = PyLong_FromLong(events);
383 if (value == NULL) {
384 Py_DECREF(key);
385 return NULL;
386 }
387 err = PyDict_SetItem(self->dict, key, value);
388 Py_DECREF(key);
389 Py_DECREF(value);
390 if (err < 0)
391 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 self->ufd_uptodate = 0;
394
395 Py_INCREF(Py_None);
396 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000397}
398
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000399PyDoc_STRVAR(poll_modify_doc,
400"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000401Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000402fd -- either an integer, or an object with a fileno() method returning an\n\
403 int.\n\
404events -- an optional bitmask describing the type of events to check for");
405
406static PyObject *
407poll_modify(pollObject *self, PyObject *args)
408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 PyObject *o, *key, *value;
410 int fd, events;
411 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
414 return NULL;
415 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 fd = PyObject_AsFileDescriptor(o);
418 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 /* Modify registered fd */
421 key = PyLong_FromLong(fd);
422 if (key == NULL)
423 return NULL;
424 if (PyDict_GetItem(self->dict, key) == NULL) {
425 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200426 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 return NULL;
428 }
429 value = PyLong_FromLong(events);
430 if (value == NULL) {
431 Py_DECREF(key);
432 return NULL;
433 }
434 err = PyDict_SetItem(self->dict, key, value);
435 Py_DECREF(key);
436 Py_DECREF(value);
437 if (err < 0)
438 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 self->ufd_uptodate = 0;
441
442 Py_INCREF(Py_None);
443 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000444}
445
446
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000447PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000449Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450
451static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 PyObject *key;
455 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 fd = PyObject_AsFileDescriptor( o );
458 if (fd == -1)
459 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 /* Check whether the fd is already in the array */
462 key = PyLong_FromLong(fd);
463 if (key == NULL)
464 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 if (PyDict_DelItem(self->dict, key) == -1) {
467 Py_DECREF(key);
468 /* This will simply raise the KeyError set by PyDict_DelItem
469 if the file descriptor isn't registered. */
470 return NULL;
471 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 Py_DECREF(key);
474 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 Py_INCREF(Py_None);
477 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000478}
479
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000480PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000481"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
482Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000483any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484
485static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 PyObject *result_list = NULL, *tout = NULL;
489 int timeout = 0, poll_result, i, j;
490 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
493 return NULL;
494 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 /* Check values for timeout */
497 if (tout == NULL || tout == Py_None)
498 timeout = -1;
499 else if (!PyNumber_Check(tout)) {
500 PyErr_SetString(PyExc_TypeError,
501 "timeout must be an integer or None");
502 return NULL;
503 }
504 else {
505 tout = PyNumber_Long(tout);
506 if (!tout)
507 return NULL;
508 timeout = PyLong_AsLong(tout);
509 Py_DECREF(tout);
510 if (timeout == -1 && PyErr_Occurred())
511 return NULL;
512 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 /* Ensure the ufd array is up to date */
515 if (!self->ufd_uptodate)
516 if (update_ufd_array(self) == 0)
517 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 /* call poll() */
520 Py_BEGIN_ALLOW_THREADS
521 poll_result = poll(self->ufds, self->ufd_len, timeout);
522 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200525 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 return NULL;
527 }
528
529 /* build the result list */
530
531 result_list = PyList_New(poll_result);
532 if (!result_list)
533 return NULL;
534 else {
535 for (i = 0, j = 0; j < poll_result; j++) {
536 /* skip to the next fired descriptor */
537 while (!self->ufds[i].revents) {
538 i++;
539 }
540 /* if we hit a NULL return, set value to NULL
541 and break out of loop; code at end will
542 clean up result_list */
543 value = PyTuple_New(2);
544 if (value == NULL)
545 goto error;
546 num = PyLong_FromLong(self->ufds[i].fd);
547 if (num == NULL) {
548 Py_DECREF(value);
549 goto error;
550 }
551 PyTuple_SET_ITEM(value, 0, num);
552
553 /* The &0xffff is a workaround for AIX. 'revents'
554 is a 16-bit short, and IBM assigned POLLNVAL
555 to be 0x8000, so the conversion to int results
556 in a negative number. See SF bug #923315. */
557 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
558 if (num == NULL) {
559 Py_DECREF(value);
560 goto error;
561 }
562 PyTuple_SET_ITEM(value, 1, num);
563 if ((PyList_SetItem(result_list, j, value)) == -1) {
564 Py_DECREF(value);
565 goto error;
566 }
567 i++;
568 }
569 }
570 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000571
572 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 Py_DECREF(result_list);
574 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000575}
576
577static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 {"register", (PyCFunction)poll_register,
579 METH_VARARGS, poll_register_doc},
580 {"modify", (PyCFunction)poll_modify,
581 METH_VARARGS, poll_modify_doc},
582 {"unregister", (PyCFunction)poll_unregister,
583 METH_O, poll_unregister_doc},
584 {"poll", (PyCFunction)poll_poll,
585 METH_VARARGS, poll_poll_doc},
586 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000587};
588
589static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000590newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 pollObject *self;
593 self = PyObject_New(pollObject, &poll_Type);
594 if (self == NULL)
595 return NULL;
596 /* ufd_uptodate is a Boolean, denoting whether the
597 array pointed to by ufds matches the contents of the dictionary. */
598 self->ufd_uptodate = 0;
599 self->ufds = NULL;
600 self->dict = PyDict_New();
601 if (self->dict == NULL) {
602 Py_DECREF(self);
603 return NULL;
604 }
605 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000606}
607
608static void
609poll_dealloc(pollObject *self)
610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 if (self->ufds != NULL)
612 PyMem_DEL(self->ufds);
613 Py_XDECREF(self->dict);
614 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000615}
616
Tim Peters0c322792002-07-17 16:49:03 +0000617static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 /* The ob_type field must be initialized in the module init function
619 * to be portable to Windows without using C++. */
620 PyVarObject_HEAD_INIT(NULL, 0)
621 "select.poll", /*tp_name*/
622 sizeof(pollObject), /*tp_basicsize*/
623 0, /*tp_itemsize*/
624 /* methods */
625 (destructor)poll_dealloc, /*tp_dealloc*/
626 0, /*tp_print*/
627 0, /*tp_getattr*/
628 0, /*tp_setattr*/
629 0, /*tp_reserved*/
630 0, /*tp_repr*/
631 0, /*tp_as_number*/
632 0, /*tp_as_sequence*/
633 0, /*tp_as_mapping*/
634 0, /*tp_hash*/
635 0, /*tp_call*/
636 0, /*tp_str*/
637 0, /*tp_getattro*/
638 0, /*tp_setattro*/
639 0, /*tp_as_buffer*/
640 Py_TPFLAGS_DEFAULT, /*tp_flags*/
641 0, /*tp_doc*/
642 0, /*tp_traverse*/
643 0, /*tp_clear*/
644 0, /*tp_richcompare*/
645 0, /*tp_weaklistoffset*/
646 0, /*tp_iter*/
647 0, /*tp_iternext*/
648 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000649};
650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000651PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000652"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000653unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654
655static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000656select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000660
661#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663 * On some systems poll() sets errno on invalid file descriptors. We test
664 * for this at runtime because this bug may be fixed or introduced between
665 * OS releases.
666 */
667static int select_have_broken_poll(void)
668{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 int poll_test;
670 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +0000673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 /* Create a file descriptor to make invalid */
675 if (pipe(filedes) < 0) {
676 return 1;
677 }
678 poll_struct.fd = filedes[0];
679 close(filedes[0]);
680 close(filedes[1]);
681 poll_test = poll(&poll_struct, 1, 0);
682 if (poll_test < 0) {
683 return 1;
684 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
685 return 1;
686 }
687 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000688}
689#endif /* __APPLE__ */
690
691#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000692
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000693#ifdef HAVE_EPOLL
694/* **************************************************************************
695 * epoll interface for Linux 2.6
696 *
697 * Written by Christian Heimes
698 * Inspired by Twisted's _epoll.pyx and select.poll()
699 */
700
701#ifdef HAVE_SYS_EPOLL_H
702#include <sys/epoll.h>
703#endif
704
705typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject_HEAD
707 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000708} pyEpoll_Object;
709
710static PyTypeObject pyEpoll_Type;
711#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
712
713static PyObject *
714pyepoll_err_closed(void)
715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
717 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000718}
719
720static int
721pyepoll_internal_close(pyEpoll_Object *self)
722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 int save_errno = 0;
724 if (self->epfd >= 0) {
725 int epfd = self->epfd;
726 self->epfd = -1;
727 Py_BEGIN_ALLOW_THREADS
728 if (close(epfd) < 0)
729 save_errno = errno;
730 Py_END_ALLOW_THREADS
731 }
732 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000733}
734
735static PyObject *
736newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 if (sizehint == -1) {
741 sizehint = FD_SETSIZE-1;
742 }
743 else if (sizehint < 1) {
744 PyErr_Format(PyExc_ValueError,
745 "sizehint must be greater zero, got %d",
746 sizehint);
747 return NULL;
748 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 assert(type != NULL && type->tp_alloc != NULL);
751 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
752 if (self == NULL)
753 return NULL;
754
755 if (fd == -1) {
756 Py_BEGIN_ALLOW_THREADS
757 self->epfd = epoll_create(sizehint);
758 Py_END_ALLOW_THREADS
759 }
760 else {
761 self->epfd = fd;
762 }
763 if (self->epfd < 0) {
764 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200765 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 return NULL;
767 }
768 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000769}
770
771
772static PyObject *
773pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 int sizehint = -1;
776 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
779 &sizehint))
780 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000783}
784
785
786static void
787pyepoll_dealloc(pyEpoll_Object *self)
788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 (void)pyepoll_internal_close(self);
790 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000791}
792
793static PyObject*
794pyepoll_close(pyEpoll_Object *self)
795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 errno = pyepoll_internal_close(self);
797 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200798 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 return NULL;
800 }
801 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000802}
803
804PyDoc_STRVAR(pyepoll_close_doc,
805"close() -> None\n\
806\n\
807Close the epoll control file descriptor. Further operations on the epoll\n\
808object will raise an exception.");
809
810static PyObject*
811pyepoll_get_closed(pyEpoll_Object *self)
812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 if (self->epfd < 0)
814 Py_RETURN_TRUE;
815 else
816 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000817}
818
819static PyObject*
820pyepoll_fileno(pyEpoll_Object *self)
821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 if (self->epfd < 0)
823 return pyepoll_err_closed();
824 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000825}
826
827PyDoc_STRVAR(pyepoll_fileno_doc,
828"fileno() -> int\n\
829\n\
830Return the epoll control file descriptor.");
831
832static PyObject*
833pyepoll_fromfd(PyObject *cls, PyObject *args)
834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
838 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000841}
842
843PyDoc_STRVAR(pyepoll_fromfd_doc,
844"fromfd(fd) -> epoll\n\
845\n\
846Create an epoll object from a given control fd.");
847
848static PyObject *
849pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 struct epoll_event ev;
852 int result;
853 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 if (epfd < 0)
856 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 fd = PyObject_AsFileDescriptor(pfd);
859 if (fd == -1) {
860 return NULL;
861 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 switch(op) {
864 case EPOLL_CTL_ADD:
865 case EPOLL_CTL_MOD:
866 ev.events = events;
867 ev.data.fd = fd;
868 Py_BEGIN_ALLOW_THREADS
869 result = epoll_ctl(epfd, op, fd, &ev);
870 Py_END_ALLOW_THREADS
871 break;
872 case EPOLL_CTL_DEL:
873 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
874 * operation required a non-NULL pointer in event, even
875 * though this argument is ignored. */
876 Py_BEGIN_ALLOW_THREADS
877 result = epoll_ctl(epfd, op, fd, &ev);
878 if (errno == EBADF) {
879 /* fd already closed */
880 result = 0;
881 errno = 0;
882 }
883 Py_END_ALLOW_THREADS
884 break;
885 default:
886 result = -1;
887 errno = EINVAL;
888 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200891 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 return NULL;
893 }
894 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000895}
896
897static PyObject *
898pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 PyObject *pfd;
901 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
902 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
905 &pfd, &events)) {
906 return NULL;
907 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000910}
911
912PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +0000913"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000914\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200915Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000916fd is the target file descriptor of the operation.\n\
917events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000918is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
919\n\
920The epoll interface supports all file descriptors that support poll.");
921
922static PyObject *
923pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 PyObject *pfd;
926 unsigned int events;
927 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
930 &pfd, &events)) {
931 return NULL;
932 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000935}
936
937PyDoc_STRVAR(pyepoll_modify_doc,
938"modify(fd, eventmask) -> None\n\
939\n\
940fd is the target file descriptor of the operation\n\
941events is a bit set composed of the various EPOLL constants");
942
943static PyObject *
944pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 PyObject *pfd;
947 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
950 &pfd)) {
951 return NULL;
952 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000955}
956
957PyDoc_STRVAR(pyepoll_unregister_doc,
958"unregister(fd) -> None\n\
959\n\
960fd is the target file descriptor of the operation.");
961
962static PyObject *
963pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 double dtimeout = -1.;
966 int timeout;
967 int maxevents = -1;
968 int nfds, i;
969 PyObject *elist = NULL, *etuple = NULL;
970 struct epoll_event *evs = NULL;
971 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 if (self->epfd < 0)
974 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
977 &dtimeout, &maxevents)) {
978 return NULL;
979 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 if (dtimeout < 0) {
982 timeout = -1;
983 }
984 else if (dtimeout * 1000.0 > INT_MAX) {
985 PyErr_SetString(PyExc_OverflowError,
986 "timeout is too large");
987 return NULL;
988 }
989 else {
990 timeout = (int)(dtimeout * 1000.0);
991 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 if (maxevents == -1) {
994 maxevents = FD_SETSIZE-1;
995 }
996 else if (maxevents < 1) {
997 PyErr_Format(PyExc_ValueError,
998 "maxevents must be greater than 0, got %d",
999 maxevents);
1000 return NULL;
1001 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 evs = PyMem_New(struct epoll_event, maxevents);
1004 if (evs == NULL) {
1005 Py_DECREF(self);
1006 PyErr_NoMemory();
1007 return NULL;
1008 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 Py_BEGIN_ALLOW_THREADS
1011 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1012 Py_END_ALLOW_THREADS
1013 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001014 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 goto error;
1016 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 elist = PyList_New(nfds);
1019 if (elist == NULL) {
1020 goto error;
1021 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 for (i = 0; i < nfds; i++) {
1024 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1025 if (etuple == NULL) {
1026 Py_CLEAR(elist);
1027 goto error;
1028 }
1029 PyList_SET_ITEM(elist, i, etuple);
1030 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001031
Christian Heimesf6cd9672008-03-26 13:45:42 +00001032 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 PyMem_Free(evs);
1034 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001035}
1036
1037PyDoc_STRVAR(pyepoll_poll_doc,
1038"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1039\n\
1040Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1041in seconds (as float). -1 makes poll wait indefinitely.\n\
1042Up to maxevents are returned to the caller.");
1043
1044static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 {"fromfd", (PyCFunction)pyepoll_fromfd,
1046 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1047 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1048 pyepoll_close_doc},
1049 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1050 pyepoll_fileno_doc},
1051 {"modify", (PyCFunction)pyepoll_modify,
1052 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1053 {"register", (PyCFunction)pyepoll_register,
1054 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1055 {"unregister", (PyCFunction)pyepoll_unregister,
1056 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1057 {"poll", (PyCFunction)pyepoll_poll,
1058 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1059 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001060};
1061
1062static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 {"closed", (getter)pyepoll_get_closed, NULL,
1064 "True if the epoll handler is closed"},
1065 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001066};
1067
1068PyDoc_STRVAR(pyepoll_doc,
1069"select.epoll([sizehint=-1])\n\
1070\n\
1071Returns an epolling object\n\
1072\n\
1073sizehint must be a positive integer or -1 for the default size. The\n\
1074sizehint is used to optimize internal data structures. It doesn't limit\n\
1075the maximum number of monitored events.");
1076
1077static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 PyVarObject_HEAD_INIT(NULL, 0)
1079 "select.epoll", /* tp_name */
1080 sizeof(pyEpoll_Object), /* tp_basicsize */
1081 0, /* tp_itemsize */
1082 (destructor)pyepoll_dealloc, /* tp_dealloc */
1083 0, /* tp_print */
1084 0, /* tp_getattr */
1085 0, /* tp_setattr */
1086 0, /* tp_reserved */
1087 0, /* tp_repr */
1088 0, /* tp_as_number */
1089 0, /* tp_as_sequence */
1090 0, /* tp_as_mapping */
1091 0, /* tp_hash */
1092 0, /* tp_call */
1093 0, /* tp_str */
1094 PyObject_GenericGetAttr, /* tp_getattro */
1095 0, /* tp_setattro */
1096 0, /* tp_as_buffer */
1097 Py_TPFLAGS_DEFAULT, /* tp_flags */
1098 pyepoll_doc, /* tp_doc */
1099 0, /* tp_traverse */
1100 0, /* tp_clear */
1101 0, /* tp_richcompare */
1102 0, /* tp_weaklistoffset */
1103 0, /* tp_iter */
1104 0, /* tp_iternext */
1105 pyepoll_methods, /* tp_methods */
1106 0, /* tp_members */
1107 pyepoll_getsetlist, /* tp_getset */
1108 0, /* tp_base */
1109 0, /* tp_dict */
1110 0, /* tp_descr_get */
1111 0, /* tp_descr_set */
1112 0, /* tp_dictoffset */
1113 0, /* tp_init */
1114 0, /* tp_alloc */
1115 pyepoll_new, /* tp_new */
1116 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001117};
1118
1119#endif /* HAVE_EPOLL */
1120
1121#ifdef HAVE_KQUEUE
1122/* **************************************************************************
1123 * kqueue interface for BSD
1124 *
1125 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1126 * All rights reserved.
1127 *
1128 * Redistribution and use in source and binary forms, with or without
1129 * modification, are permitted provided that the following conditions
1130 * are met:
1131 * 1. Redistributions of source code must retain the above copyright
1132 * notice, this list of conditions and the following disclaimer.
1133 * 2. Redistributions in binary form must reproduce the above copyright
1134 * notice, this list of conditions and the following disclaimer in the
1135 * documentation and/or other materials provided with the distribution.
1136 *
1137 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1138 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1139 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1140 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1141 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1142 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1143 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1144 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1145 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1146 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1147 * SUCH DAMAGE.
1148 */
1149
1150#ifdef HAVE_SYS_EVENT_H
1151#include <sys/event.h>
1152#endif
1153
1154PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001155"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001156\n\
1157This object is the equivalent of the struct kevent for the C API.\n\
1158\n\
1159See the kqueue manpage for more detailed information about the meaning\n\
1160of the arguments.\n\
1161\n\
1162One minor note: while you might hope that udata could store a\n\
1163reference to a python object, it cannot, because it is impossible to\n\
1164keep a proper reference count of the object once it's passed into the\n\
1165kernel. Therefore, I have restricted it to only storing an integer. I\n\
1166recommend ignoring it and simply using the 'ident' field to key off\n\
1167of. You could also set up a dictionary on the python side to store a\n\
1168udata->object mapping.");
1169
1170typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 PyObject_HEAD
1172 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001173} kqueue_event_Object;
1174
1175static PyTypeObject kqueue_event_Type;
1176
1177#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1178
1179typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 PyObject_HEAD
1181 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001182} kqueue_queue_Object;
1183
1184static PyTypeObject kqueue_queue_Type;
1185
1186#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1187
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001188#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1189# error uintptr_t does not match void *!
1190#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1191# define T_UINTPTRT T_ULONGLONG
1192# define T_INTPTRT T_LONGLONG
1193# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1194# define UINTPTRT_FMT_UNIT "K"
1195# define INTPTRT_FMT_UNIT "L"
1196#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1197# define T_UINTPTRT T_ULONG
1198# define T_INTPTRT T_LONG
1199# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1200# define UINTPTRT_FMT_UNIT "k"
1201# define INTPTRT_FMT_UNIT "l"
1202#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1203# define T_UINTPTRT T_UINT
1204# define T_INTPTRT T_INT
1205# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1206# define UINTPTRT_FMT_UNIT "I"
1207# define INTPTRT_FMT_UNIT "i"
1208#else
1209# error uintptr_t does not match int, long, or long long!
1210#endif
1211
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001212/* Unfortunately, we can't store python objects in udata, because
1213 * kevents in the kernel can be removed without warning, which would
1214 * forever lose the refcount on the object stored with it.
1215 */
1216
1217#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1218static struct PyMemberDef kqueue_event_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1220 {"filter", T_SHORT, KQ_OFF(e.filter)},
1221 {"flags", T_USHORT, KQ_OFF(e.flags)},
1222 {"fflags", T_UINT, KQ_OFF(e.fflags)},
1223 {"data", T_INTPTRT, KQ_OFF(e.data)},
1224 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1225 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001226};
1227#undef KQ_OFF
1228
1229static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001230
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231kqueue_event_repr(kqueue_event_Object *s)
1232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 char buf[1024];
1234 PyOS_snprintf(
1235 buf, sizeof(buf),
1236 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1237 "data=0x%zd udata=%p>",
1238 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1239 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1240 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001241}
1242
1243static int
1244kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 PyObject *pfd;
1247 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1248 "data", "udata", NULL};
1249 static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1254 &pfd, &(self->e.filter), &(self->e.flags),
1255 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1256 return -1;
1257 }
1258
1259 if (PyLong_Check(pfd)) {
1260 self->e.ident = PyLong_AsUintptr_t(pfd);
1261 }
1262 else {
1263 self->e.ident = PyObject_AsFileDescriptor(pfd);
1264 }
1265 if (PyErr_Occurred()) {
1266 return -1;
1267 }
1268 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001269}
1270
1271static PyObject *
1272kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 if (!kqueue_event_Check(o)) {
1278 if (op == Py_EQ || op == Py_NE) {
1279 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1280 Py_INCREF(res);
1281 return res;
1282 }
1283 PyErr_Format(PyExc_TypeError,
1284 "can't compare %.200s to %.200s",
1285 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1286 return NULL;
1287 }
1288 if (((result = s->e.ident - o->e.ident) == 0) &&
1289 ((result = s->e.filter - o->e.filter) == 0) &&
1290 ((result = s->e.flags - o->e.flags) == 0) &&
1291 ((result = s->e.fflags - o->e.fflags) == 0) &&
1292 ((result = s->e.data - o->e.data) == 0) &&
1293 ((result = s->e.udata - o->e.udata) == 0)
1294 ) {
1295 result = 0;
1296 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 switch (op) {
1299 case Py_EQ:
1300 result = (result == 0);
1301 break;
1302 case Py_NE:
1303 result = (result != 0);
1304 break;
1305 case Py_LE:
1306 result = (result <= 0);
1307 break;
1308 case Py_GE:
1309 result = (result >= 0);
1310 break;
1311 case Py_LT:
1312 result = (result < 0);
1313 break;
1314 case Py_GT:
1315 result = (result > 0);
1316 break;
1317 }
1318 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001319}
1320
1321static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 PyVarObject_HEAD_INIT(NULL, 0)
1323 "select.kevent", /* tp_name */
1324 sizeof(kqueue_event_Object), /* tp_basicsize */
1325 0, /* tp_itemsize */
1326 0, /* tp_dealloc */
1327 0, /* tp_print */
1328 0, /* tp_getattr */
1329 0, /* tp_setattr */
1330 0, /* tp_reserved */
1331 (reprfunc)kqueue_event_repr, /* tp_repr */
1332 0, /* tp_as_number */
1333 0, /* tp_as_sequence */
1334 0, /* tp_as_mapping */
1335 0, /* tp_hash */
1336 0, /* tp_call */
1337 0, /* tp_str */
1338 0, /* tp_getattro */
1339 0, /* tp_setattro */
1340 0, /* tp_as_buffer */
1341 Py_TPFLAGS_DEFAULT, /* tp_flags */
1342 kqueue_event_doc, /* tp_doc */
1343 0, /* tp_traverse */
1344 0, /* tp_clear */
1345 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1346 0, /* tp_weaklistoffset */
1347 0, /* tp_iter */
1348 0, /* tp_iternext */
1349 0, /* tp_methods */
1350 kqueue_event_members, /* tp_members */
1351 0, /* tp_getset */
1352 0, /* tp_base */
1353 0, /* tp_dict */
1354 0, /* tp_descr_get */
1355 0, /* tp_descr_set */
1356 0, /* tp_dictoffset */
1357 (initproc)kqueue_event_init, /* tp_init */
1358 0, /* tp_alloc */
1359 0, /* tp_new */
1360 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361};
1362
1363static PyObject *
1364kqueue_queue_err_closed(void)
1365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1367 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368}
1369
1370static int
1371kqueue_queue_internal_close(kqueue_queue_Object *self)
1372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 int save_errno = 0;
1374 if (self->kqfd >= 0) {
1375 int kqfd = self->kqfd;
1376 self->kqfd = -1;
1377 Py_BEGIN_ALLOW_THREADS
1378 if (close(kqfd) < 0)
1379 save_errno = errno;
1380 Py_END_ALLOW_THREADS
1381 }
1382 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383}
1384
1385static PyObject *
1386newKqueue_Object(PyTypeObject *type, SOCKET fd)
1387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 kqueue_queue_Object *self;
1389 assert(type != NULL && type->tp_alloc != NULL);
1390 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1391 if (self == NULL) {
1392 return NULL;
1393 }
1394
1395 if (fd == -1) {
1396 Py_BEGIN_ALLOW_THREADS
1397 self->kqfd = kqueue();
1398 Py_END_ALLOW_THREADS
1399 }
1400 else {
1401 self->kqfd = fd;
1402 }
1403 if (self->kqfd < 0) {
1404 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001405 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 return NULL;
1407 }
1408 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001409}
1410
1411static PyObject *
1412kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1413{
1414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 if ((args != NULL && PyObject_Size(args)) ||
1416 (kwds != NULL && PyObject_Size(kwds))) {
1417 PyErr_SetString(PyExc_ValueError,
1418 "select.kqueue doesn't accept arguments");
1419 return NULL;
1420 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001423}
1424
1425static void
1426kqueue_queue_dealloc(kqueue_queue_Object *self)
1427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 kqueue_queue_internal_close(self);
1429 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001430}
1431
1432static PyObject*
1433kqueue_queue_close(kqueue_queue_Object *self)
1434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 errno = kqueue_queue_internal_close(self);
1436 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001437 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 return NULL;
1439 }
1440 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441}
1442
1443PyDoc_STRVAR(kqueue_queue_close_doc,
1444"close() -> None\n\
1445\n\
1446Close the kqueue control file descriptor. Further operations on the kqueue\n\
1447object will raise an exception.");
1448
1449static PyObject*
1450kqueue_queue_get_closed(kqueue_queue_Object *self)
1451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 if (self->kqfd < 0)
1453 Py_RETURN_TRUE;
1454 else
1455 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001456}
1457
1458static PyObject*
1459kqueue_queue_fileno(kqueue_queue_Object *self)
1460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 if (self->kqfd < 0)
1462 return kqueue_queue_err_closed();
1463 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001464}
1465
1466PyDoc_STRVAR(kqueue_queue_fileno_doc,
1467"fileno() -> int\n\
1468\n\
1469Return the kqueue control file descriptor.");
1470
1471static PyObject*
1472kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1477 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480}
1481
1482PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1483"fromfd(fd) -> kqueue\n\
1484\n\
1485Create a kqueue object from a given control fd.");
1486
1487static PyObject *
1488kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 int nevents = 0;
1491 int gotevents = 0;
1492 int nchanges = 0;
1493 int i = 0;
1494 PyObject *otimeout = NULL;
1495 PyObject *ch = NULL;
1496 PyObject *it = NULL, *ei = NULL;
1497 PyObject *result = NULL;
1498 struct kevent *evl = NULL;
1499 struct kevent *chl = NULL;
1500 struct timespec timeoutspec;
1501 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 if (self->kqfd < 0)
1504 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1507 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 if (nevents < 0) {
1510 PyErr_Format(PyExc_ValueError,
1511 "Length of eventlist must be 0 or positive, got %d",
1512 nevents);
1513 return NULL;
1514 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 if (otimeout == Py_None || otimeout == NULL) {
1517 ptimeoutspec = NULL;
1518 }
1519 else if (PyNumber_Check(otimeout)) {
1520 double timeout;
1521 long seconds;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 timeout = PyFloat_AsDouble(otimeout);
1524 if (timeout == -1 && PyErr_Occurred())
1525 return NULL;
1526 if (timeout > (double)LONG_MAX) {
1527 PyErr_SetString(PyExc_OverflowError,
1528 "timeout period too long");
1529 return NULL;
1530 }
1531 if (timeout < 0) {
1532 PyErr_SetString(PyExc_ValueError,
1533 "timeout must be positive or None");
1534 return NULL;
1535 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 seconds = (long)timeout;
1538 timeout = timeout - (double)seconds;
1539 timeoutspec.tv_sec = seconds;
1540 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1541 ptimeoutspec = &timeoutspec;
1542 }
1543 else {
1544 PyErr_Format(PyExc_TypeError,
1545 "timeout argument must be an number "
1546 "or None, got %.200s",
1547 Py_TYPE(otimeout)->tp_name);
1548 return NULL;
1549 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 if (ch != NULL && ch != Py_None) {
1552 it = PyObject_GetIter(ch);
1553 if (it == NULL) {
1554 PyErr_SetString(PyExc_TypeError,
1555 "changelist is not iterable");
1556 return NULL;
1557 }
1558 nchanges = PyObject_Size(ch);
1559 if (nchanges < 0) {
1560 goto error;
1561 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00001562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 chl = PyMem_New(struct kevent, nchanges);
1564 if (chl == NULL) {
1565 PyErr_NoMemory();
1566 goto error;
1567 }
1568 i = 0;
1569 while ((ei = PyIter_Next(it)) != NULL) {
1570 if (!kqueue_event_Check(ei)) {
1571 Py_DECREF(ei);
1572 PyErr_SetString(PyExc_TypeError,
1573 "changelist must be an iterable of "
1574 "select.kevent objects");
1575 goto error;
1576 } else {
1577 chl[i++] = ((kqueue_event_Object *)ei)->e;
1578 }
1579 Py_DECREF(ei);
1580 }
1581 }
1582 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 /* event list */
1585 if (nevents) {
1586 evl = PyMem_New(struct kevent, nevents);
1587 if (evl == NULL) {
1588 PyErr_NoMemory();
1589 goto error;
1590 }
1591 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 Py_BEGIN_ALLOW_THREADS
1594 gotevents = kevent(self->kqfd, chl, nchanges,
1595 evl, nevents, ptimeoutspec);
1596 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 if (gotevents == -1) {
1599 PyErr_SetFromErrno(PyExc_OSError);
1600 goto error;
1601 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 result = PyList_New(gotevents);
1604 if (result == NULL) {
1605 goto error;
1606 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 for (i = 0; i < gotevents; i++) {
1609 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1612 if (ch == NULL) {
1613 goto error;
1614 }
1615 ch->e = evl[i];
1616 PyList_SET_ITEM(result, i, (PyObject *)ch);
1617 }
1618 PyMem_Free(chl);
1619 PyMem_Free(evl);
1620 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001621
1622 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 PyMem_Free(chl);
1624 PyMem_Free(evl);
1625 Py_XDECREF(result);
1626 Py_XDECREF(it);
1627 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001628}
1629
1630PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00001631"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632\n\
1633Calls the kernel kevent function.\n\
1634- changelist must be a list of kevent objects describing the changes\n\
1635 to be made to the kernel's watch list or None.\n\
1636- max_events lets you specify the maximum number of events that the\n\
1637 kernel will return.\n\
1638- timeout is the maximum time to wait in seconds, or else None,\n\
1639 to wait forever. timeout accepts floats for smaller timeouts, too.");
1640
1641
1642static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1644 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1645 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1646 kqueue_queue_close_doc},
1647 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1648 kqueue_queue_fileno_doc},
1649 {"control", (PyCFunction)kqueue_queue_control,
1650 METH_VARARGS , kqueue_queue_control_doc},
1651 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652};
1653
1654static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 {"closed", (getter)kqueue_queue_get_closed, NULL,
1656 "True if the kqueue handler is closed"},
1657 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001658};
1659
1660PyDoc_STRVAR(kqueue_queue_doc,
1661"Kqueue syscall wrapper.\n\
1662\n\
1663For example, to start watching a socket for input:\n\
1664>>> kq = kqueue()\n\
1665>>> sock = socket()\n\
1666>>> sock.connect((host, port))\n\
1667>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1668\n\
1669To wait one second for it to become writeable:\n\
1670>>> kq.control(None, 1, 1000)\n\
1671\n\
1672To stop listening:\n\
1673>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1674
1675static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 PyVarObject_HEAD_INIT(NULL, 0)
1677 "select.kqueue", /* tp_name */
1678 sizeof(kqueue_queue_Object), /* tp_basicsize */
1679 0, /* tp_itemsize */
1680 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1681 0, /* tp_print */
1682 0, /* tp_getattr */
1683 0, /* tp_setattr */
1684 0, /* tp_reserved */
1685 0, /* 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_queue_doc, /* tp_doc */
1697 0, /* tp_traverse */
1698 0, /* tp_clear */
1699 0, /* tp_richcompare */
1700 0, /* tp_weaklistoffset */
1701 0, /* tp_iter */
1702 0, /* tp_iternext */
1703 kqueue_queue_methods, /* tp_methods */
1704 0, /* tp_members */
1705 kqueue_queue_getsetlist, /* 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 0, /* tp_init */
1712 0, /* tp_alloc */
1713 kqueue_queue_new, /* tp_new */
1714 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001715};
1716
1717#endif /* HAVE_KQUEUE */
1718/* ************************************************************************ */
1719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001720PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001721"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1722\n\
1723Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001724The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001725rlist -- wait until ready for reading\n\
1726wlist -- wait until ready for writing\n\
1727xlist -- wait for an ``exceptional condition''\n\
1728If only one kind of condition is required, pass [] for the other lists.\n\
1729A file descriptor is either a socket or file object, or a small integer\n\
1730gotten from a fileno() method call on one of those.\n\
1731\n\
1732The optional 4th argument specifies a timeout in seconds; it may be\n\
1733a floating point number to specify fractions of seconds. If it is absent\n\
1734or None, the call will never time out.\n\
1735\n\
1736The return value is a tuple of three lists corresponding to the first three\n\
1737arguments; each contains the subset of the corresponding file descriptors\n\
1738that are ready.\n\
1739\n\
1740*** IMPORTANT NOTICE ***\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001742descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001743
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001744static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 {"select", select_select, METH_VARARGS, select_doc},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001746#ifdef HAVE_POLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748#endif /* HAVE_POLL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001750};
1751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001753"This module supports asynchronous I/O on multiple file descriptors.\n\
1754\n\
1755*** IMPORTANT NOTICE ***\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001756On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001757
Martin v. Löwis1a214512008-06-11 05:26:20 +00001758
1759static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 PyModuleDef_HEAD_INIT,
1761 "select",
1762 module_doc,
1763 -1,
1764 select_methods,
1765 NULL,
1766 NULL,
1767 NULL,
1768 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001769};
1770
Mark Hammond62b1ab12002-07-23 06:31:15 +00001771PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001772PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 PyObject *m;
1775 m = PyModule_Create(&selectmodule);
1776 if (m == NULL)
1777 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00001778
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001779 Py_INCREF(PyExc_OSError);
1780 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001781
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001782#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00001783#ifdef HAVE_BROKEN_PIPE_BUF
1784#undef PIPE_BUF
1785#define PIPE_BUF 512
1786#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00001788#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00001789
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001790#if defined(HAVE_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001791#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 if (select_have_broken_poll()) {
1793 if (PyObject_DelAttrString(m, "poll") == -1) {
1794 PyErr_Clear();
1795 }
1796 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001797#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001799#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 if (PyType_Ready(&poll_Type) < 0)
1801 return NULL;
1802 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1803 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1804 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1805 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1806 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1807 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001808
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001809#ifdef POLLRDNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001811#endif
1812#ifdef POLLRDBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001814#endif
1815#ifdef POLLWRNORM
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001817#endif
1818#ifdef POLLWRBAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001820#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001821#ifdef POLLMSG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001823#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001825#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001826
1827#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1829 if (PyType_Ready(&pyEpoll_Type) < 0)
1830 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 Py_INCREF(&pyEpoll_Type);
1833 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1836 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1837 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1838 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1839 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1840 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 /* Kernel 2.6.2+ */
1843 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001844#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1846 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1847 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1848 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1849 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1850 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001851#endif /* HAVE_EPOLL */
1852
1853#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 kqueue_event_Type.tp_new = PyType_GenericNew;
1855 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1856 if(PyType_Ready(&kqueue_event_Type) < 0)
1857 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 Py_INCREF(&kqueue_event_Type);
1860 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1863 if(PyType_Ready(&kqueue_queue_Type) < 0)
1864 return NULL;
1865 Py_INCREF(&kqueue_queue_Type);
1866 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1867
1868 /* event filters */
1869 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1870 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1871 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1872 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1873 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001874#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1878 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 /* event flags */
1881 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1882 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1883 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1884 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1885 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1886 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1889 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1892 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 /* READ WRITE filter flag */
1895 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 /* VNODE filter flags */
1898 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1899 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1900 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1901 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1902 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1903 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1904 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 /* PROC filter flags */
1907 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1908 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1909 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1910 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1911 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1915 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1916
1917 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001918#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1920 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1921 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001922#endif
1923
1924#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00001926}