blob: 6a3652160a944fe91c173fac60211c5212a06c1a [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Christian Heimes0e9ab5f2008-03-21 23:49:44 +000010#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000011
Ronald Oussoren32fd16e2006-04-23 12:36:23 +000012#ifdef __APPLE__
13 /* Perform runtime testing for a broken poll on OSX to make it easier
14 * to use the same binary on multiple releases of the OS.
15 */
16#undef HAVE_BROKEN_POLL
17#endif
18
Tim Petersd92dfe02000-12-12 01:18:41 +000019/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
20 64 is too small (too many people have bumped into that limit).
21 Here we boost it.
22 Users who want even more than the boosted limit should #define
23 FD_SETSIZE higher before this; e.g., via compiler /D switch.
24*/
25#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
26#define FD_SETSIZE 512
Antoine Pitrouc83ea132010-05-09 14:46:46 +000027#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000028
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000029#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000030#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000031#elif defined(HAVE_SYS_POLL_H)
32#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000033#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000034
Guido van Rossum37273171996-12-09 18:47:43 +000035#ifdef __sgi
36/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000037extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000038#endif
39
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000040#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000042#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043
Andrew MacIntyre7bf68332002-03-03 02:59:16 +000044#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#include <sys/time.h>
46#include <utils.h>
47#endif
48
Guido van Rossum6f489d91996-06-28 20:15:15 +000049#ifdef MS_WINDOWS
Kristján Valur Jónssonf6f3c4a2010-11-03 13:27:33 +000050# include <winsock2.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051#else
Neal Norwitz2a30cd02006-07-10 01:18:57 +000052# define SOCKET int
53# ifdef __BEOS__
54# include <net/socket.h>
55# elif defined(__VMS)
56# include <socket.h>
57# endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000058#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000059
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000060static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000061
Barry Warsawc1cb3601996-12-12 22:16:21 +000062/* list of Python objects and their file descriptor */
63typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000064 PyObject *obj; /* owned reference */
65 SOCKET fd;
66 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000067} pylist;
68
Barry Warsawc1cb3601996-12-12 22:16:21 +000069static void
Tim Peters4b046c22001-08-16 21:59:46 +000070reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000071{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000072 int i;
73 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
74 Py_XDECREF(fd2obj[i].obj);
75 fd2obj[i].obj = NULL;
76 }
77 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000078}
79
80
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000081/* returns -1 and sets the Python exception if an error occurred, otherwise
82 returns a number >= 0
83*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000084static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000085seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000086{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000087 int i;
88 int max = -1;
89 int index = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000090 PyObject* fast_seq = NULL;
91 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000092
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
94 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000095
Antoine Pitrouc83ea132010-05-09 14:46:46 +000096 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
97 if (!fast_seq)
98 return -1;
99
Antoine Pitrou0552fc22012-11-01 20:13:54 +0100100 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Brett Cannon62dba4c2003-09-10 19:37:42 +0000105 return -1;
106
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000107 Py_INCREF(o);
108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000112 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#else /* !_MSC_VER */
Charles-François Natalifda7b372011-08-28 16:22:33 +0200114 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
134 }
135 Py_DECREF(fast_seq);
136 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000137
138 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000139 Py_XDECREF(o);
140 Py_DECREF(fast_seq);
141 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000142}
143
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000144/* returns NULL and sets the Python exception if an error occurred */
145static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000146set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000147{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000148 int i, j, count=0;
149 PyObject *list, *o;
150 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000151
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000152 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
153 if (FD_ISSET(fd2obj[j].fd, set))
154 count++;
155 }
156 list = PyList_New(count);
157 if (!list)
158 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000160 i = 0;
161 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
162 fd = fd2obj[j].fd;
163 if (FD_ISSET(fd, set)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000164 o = fd2obj[j].obj;
165 fd2obj[j].obj = NULL;
166 /* transfer ownership */
167 if (PyList_SetItem(list, i, o) < 0)
168 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000169
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000170 i++;
171 }
172 }
173 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000174 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000175 Py_DECREF(list);
176 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000177}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000178
Barry Warsawb44740f2001-08-16 16:52:59 +0000179#undef SELECT_USES_HEAP
180#if FD_SETSIZE > 1024
181#define SELECT_USES_HEAP
182#endif /* FD_SETSIZE > 1024 */
183
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000184static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000185select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000186{
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000188 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000189#else /* !SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000190 /* XXX: All this should probably be implemented as follows:
191 * - find the highest descriptor we're interested in
192 * - add one
193 * - that's the size
194 * See: Stevens, APitUE, $12.5.1
195 */
196 pylist rfd2obj[FD_SETSIZE + 1];
197 pylist wfd2obj[FD_SETSIZE + 1];
198 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000199#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000200 PyObject *ifdlist, *ofdlist, *efdlist;
201 PyObject *ret = NULL;
202 PyObject *tout = Py_None;
203 fd_set ifdset, ofdset, efdset;
204 double timeout;
205 struct timeval tv, *tvp;
206 long seconds;
207 int imax, omax, emax, max;
208 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000209
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000210 /* convert arguments */
211 if (!PyArg_UnpackTuple(args, "select", 3, 4,
212 &ifdlist, &ofdlist, &efdlist, &tout))
213 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000214
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 if (tout == Py_None)
216 tvp = (struct timeval *)0;
217 else if (!PyNumber_Check(tout)) {
218 PyErr_SetString(PyExc_TypeError,
219 "timeout must be a float or None");
220 return NULL;
221 }
222 else {
223 timeout = PyFloat_AsDouble(tout);
224 if (timeout == -1 && PyErr_Occurred())
225 return NULL;
226 if (timeout > (double)LONG_MAX) {
227 PyErr_SetString(PyExc_OverflowError,
228 "timeout period too long");
229 return NULL;
230 }
231 seconds = (long)timeout;
232 timeout = timeout - (double)seconds;
233 tv.tv_sec = seconds;
234 tv.tv_usec = (long)(timeout * 1E6);
235 tvp = &tv;
236 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000237
Guido van Rossumed233a51992-06-23 09:07:03 +0000238
Barry Warsawb44740f2001-08-16 16:52:59 +0000239#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000240 /* Allocate memory for the lists */
241 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
242 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
243 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
244 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
245 if (rfd2obj) PyMem_DEL(rfd2obj);
246 if (wfd2obj) PyMem_DEL(wfd2obj);
247 if (efd2obj) PyMem_DEL(efd2obj);
248 return PyErr_NoMemory();
249 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000251 /* Convert sequences to fd_sets, and get maximum fd number
252 * propagates the Python exception set in seq2set()
253 */
254 rfd2obj[0].sentinel = -1;
255 wfd2obj[0].sentinel = -1;
256 efd2obj[0].sentinel = -1;
257 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
258 goto finally;
259 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
260 goto finally;
261 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
262 goto finally;
263 max = imax;
264 if (omax > max) max = omax;
265 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000266
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000267 Py_BEGIN_ALLOW_THREADS
268 n = select(max, &ifdset, &ofdset, &efdset, tvp);
269 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000270
Thomas Heller106f4c72002-09-24 16:51:00 +0000271#ifdef MS_WINDOWS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 if (n == SOCKET_ERROR) {
273 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
274 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000275#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 if (n < 0) {
277 PyErr_SetFromErrno(SelectError);
278 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000279#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000280 else {
281 /* any of these three calls can raise an exception. it's more
282 convenient to test for this after all three calls... but
283 is that acceptable?
284 */
285 ifdlist = set2list(&ifdset, rfd2obj);
286 ofdlist = set2list(&ofdset, wfd2obj);
287 efdlist = set2list(&efdset, efd2obj);
288 if (PyErr_Occurred())
289 ret = NULL;
290 else
291 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000292
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293 Py_DECREF(ifdlist);
294 Py_DECREF(ofdlist);
295 Py_DECREF(efdlist);
296 }
297
Barry Warsawc1cb3601996-12-12 22:16:21 +0000298 finally:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299 reap_obj(rfd2obj);
300 reap_obj(wfd2obj);
301 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000302#ifdef SELECT_USES_HEAP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000303 PyMem_DEL(rfd2obj);
304 PyMem_DEL(wfd2obj);
305 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000306#endif /* SELECT_USES_HEAP */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000307 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000308}
309
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000310#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000311/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000312 * poll() support
313 */
314
315typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000316 PyObject_HEAD
317 PyObject *dict;
318 int ufd_uptodate;
319 int ufd_len;
320 struct pollfd *ufds;
Serhiy Storchakac3603892013-08-20 20:38:21 +0300321 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000322} pollObject;
323
Jeremy Hylton938ace62002-07-17 16:30:39 +0000324static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000325
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000326/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000327 contained within a pollObject. Return 1 on success, 0 on an error.
328*/
329
330static int
331update_ufd_array(pollObject *self)
332{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000333 Py_ssize_t i, pos;
334 PyObject *key, *value;
335 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000336
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000337 self->ufd_len = PyDict_Size(self->dict);
338 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
339 if (self->ufds == NULL) {
340 self->ufds = old_ufds;
341 PyErr_NoMemory();
342 return 0;
343 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000344
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000345 i = pos = 0;
346 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200347 assert(i < self->ufd_len);
348 /* Never overflow */
349 self->ufds[i].fd = (int)PyInt_AsLong(key);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000350 self->ufds[i].events = (short)PyInt_AsLong(value);
351 i++;
352 }
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200353 assert(i == self->ufd_len);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000354 self->ufd_uptodate = 1;
355 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000356}
357
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000358PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359"register(fd [, eventmask] ) -> None\n\n\
360Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000361fd -- either an integer, or an object with a fileno() method returning an\n\
362 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000363events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000364
365static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000366poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000368 PyObject *o, *key, *value;
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200369 int fd;
370 short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000371 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000372
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200373 if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000374 return NULL;
375 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000376
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000377 fd = PyObject_AsFileDescriptor(o);
378 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000379
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000380 /* Add entry to the internal dictionary: the key is the
381 file descriptor, and the value is the event mask. */
382 key = PyInt_FromLong(fd);
383 if (key == NULL)
384 return NULL;
385 value = PyInt_FromLong(events);
386 if (value == NULL) {
387 Py_DECREF(key);
388 return NULL;
389 }
390 err = PyDict_SetItem(self->dict, key, value);
391 Py_DECREF(key);
392 Py_DECREF(value);
393 if (err < 0)
394 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000395
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000396 self->ufd_uptodate = 0;
397
398 Py_INCREF(Py_None);
399 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400}
401
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000402PyDoc_STRVAR(poll_modify_doc,
403"modify(fd, eventmask) -> None\n\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000404Modify an already registered file descriptor.\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000405fd -- either an integer, or an object with a fileno() method returning an\n\
406 int.\n\
407events -- an optional bitmask describing the type of events to check for");
408
409static PyObject *
410poll_modify(pollObject *self, PyObject *args)
411{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000412 PyObject *o, *key, *value;
413 int fd, events;
414 int err;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000415
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000416 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
417 return NULL;
418 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000419
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000420 fd = PyObject_AsFileDescriptor(o);
421 if (fd == -1) return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000422
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000423 /* Modify registered fd */
424 key = PyInt_FromLong(fd);
425 if (key == NULL)
426 return NULL;
427 if (PyDict_GetItem(self->dict, key) == NULL) {
428 errno = ENOENT;
429 PyErr_SetFromErrno(PyExc_IOError);
430 return NULL;
431 }
432 value = PyInt_FromLong(events);
433 if (value == NULL) {
434 Py_DECREF(key);
435 return NULL;
436 }
437 err = PyDict_SetItem(self->dict, key, value);
438 Py_DECREF(key);
439 Py_DECREF(value);
440 if (err < 0)
441 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000442
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000443 self->ufd_uptodate = 0;
444
445 Py_INCREF(Py_None);
446 return Py_None;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000447}
448
449
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000450PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000451"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000452Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000453
454static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000455poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000456{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000457 PyObject *key;
458 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000459
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000460 fd = PyObject_AsFileDescriptor( o );
461 if (fd == -1)
462 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000463
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000464 /* Check whether the fd is already in the array */
465 key = PyInt_FromLong(fd);
466 if (key == NULL)
467 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000468
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000469 if (PyDict_DelItem(self->dict, key) == -1) {
470 Py_DECREF(key);
471 /* This will simply raise the KeyError set by PyDict_DelItem
472 if the file descriptor isn't registered. */
473 return NULL;
474 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000476 Py_DECREF(key);
477 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000478
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000479 Py_INCREF(Py_None);
480 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000481}
482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000483PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
485Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000486any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487
488static PyObject *
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000489poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000490{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000491 PyObject *result_list = NULL, *tout = NULL;
492 int timeout = 0, poll_result, i, j;
493 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000495 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
496 return NULL;
497 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000499 /* Check values for timeout */
500 if (tout == NULL || tout == Py_None)
501 timeout = -1;
502 else if (!PyNumber_Check(tout)) {
503 PyErr_SetString(PyExc_TypeError,
504 "timeout must be an integer or None");
505 return NULL;
506 }
507 else {
508 tout = PyNumber_Int(tout);
509 if (!tout)
510 return NULL;
Serhiy Storchaka74f49ab2013-01-19 12:55:39 +0200511 timeout = _PyInt_AsInt(tout);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000512 Py_DECREF(tout);
513 if (timeout == -1 && PyErr_Occurred())
514 return NULL;
515 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000516
Serhiy Storchakac3603892013-08-20 20:38:21 +0300517 /* Avoid concurrent poll() invocation, issue 8865 */
518 if (self->poll_running) {
519 PyErr_SetString(PyExc_RuntimeError,
520 "concurrent poll() invocation");
521 return NULL;
522 }
523
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000524 /* Ensure the ufd array is up to date */
525 if (!self->ufd_uptodate)
526 if (update_ufd_array(self) == 0)
527 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000528
Serhiy Storchakac3603892013-08-20 20:38:21 +0300529 self->poll_running = 1;
530
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000531 /* call poll() */
532 Py_BEGIN_ALLOW_THREADS
533 poll_result = poll(self->ufds, self->ufd_len, timeout);
534 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000535
Serhiy Storchakac3603892013-08-20 20:38:21 +0300536 self->poll_running = 0;
537
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000538 if (poll_result < 0) {
539 PyErr_SetFromErrno(SelectError);
540 return NULL;
541 }
542
543 /* build the result list */
544
545 result_list = PyList_New(poll_result);
546 if (!result_list)
547 return NULL;
548 else {
549 for (i = 0, j = 0; j < poll_result; j++) {
550 /* skip to the next fired descriptor */
551 while (!self->ufds[i].revents) {
552 i++;
553 }
554 /* if we hit a NULL return, set value to NULL
555 and break out of loop; code at end will
556 clean up result_list */
557 value = PyTuple_New(2);
558 if (value == NULL)
559 goto error;
560 num = PyInt_FromLong(self->ufds[i].fd);
561 if (num == NULL) {
562 Py_DECREF(value);
563 goto error;
564 }
565 PyTuple_SET_ITEM(value, 0, num);
566
567 /* The &0xffff is a workaround for AIX. 'revents'
568 is a 16-bit short, and IBM assigned POLLNVAL
569 to be 0x8000, so the conversion to int results
570 in a negative number. See SF bug #923315. */
571 num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
572 if (num == NULL) {
573 Py_DECREF(value);
574 goto error;
575 }
576 PyTuple_SET_ITEM(value, 1, num);
577 if ((PyList_SetItem(result_list, j, value)) == -1) {
578 Py_DECREF(value);
579 goto error;
580 }
581 i++;
582 }
583 }
584 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000585
586 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000587 Py_DECREF(result_list);
588 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000589}
590
591static PyMethodDef poll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000592 {"register", (PyCFunction)poll_register,
593 METH_VARARGS, poll_register_doc},
594 {"modify", (PyCFunction)poll_modify,
595 METH_VARARGS, poll_modify_doc},
596 {"unregister", (PyCFunction)poll_unregister,
597 METH_O, poll_unregister_doc},
598 {"poll", (PyCFunction)poll_poll,
599 METH_VARARGS, poll_poll_doc},
600 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000601};
602
603static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000604newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000605{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000606 pollObject *self;
607 self = PyObject_New(pollObject, &poll_Type);
608 if (self == NULL)
609 return NULL;
610 /* ufd_uptodate is a Boolean, denoting whether the
611 array pointed to by ufds matches the contents of the dictionary. */
612 self->ufd_uptodate = 0;
613 self->ufds = NULL;
Serhiy Storchakac3603892013-08-20 20:38:21 +0300614 self->poll_running = 0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000615 self->dict = PyDict_New();
616 if (self->dict == NULL) {
617 Py_DECREF(self);
618 return NULL;
619 }
620 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000621}
622
623static void
624poll_dealloc(pollObject *self)
625{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000626 if (self->ufds != NULL)
627 PyMem_DEL(self->ufds);
628 Py_XDECREF(self->dict);
629 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000630}
631
632static PyObject *
633poll_getattr(pollObject *self, char *name)
634{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000635 return Py_FindMethod(poll_methods, (PyObject *)self, name);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000636}
637
Tim Peters0c322792002-07-17 16:49:03 +0000638static PyTypeObject poll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000639 /* The ob_type field must be initialized in the module init function
640 * to be portable to Windows without using C++. */
641 PyVarObject_HEAD_INIT(NULL, 0)
642 "select.poll", /*tp_name*/
643 sizeof(pollObject), /*tp_basicsize*/
644 0, /*tp_itemsize*/
645 /* methods */
646 (destructor)poll_dealloc, /*tp_dealloc*/
647 0, /*tp_print*/
648 (getattrfunc)poll_getattr, /*tp_getattr*/
649 0, /*tp_setattr*/
650 0, /*tp_compare*/
651 0, /*tp_repr*/
652 0, /*tp_as_number*/
653 0, /*tp_as_sequence*/
654 0, /*tp_as_mapping*/
655 0, /*tp_hash*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000656};
657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000658PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000660unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000661
662static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +0000663select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000664{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000665 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000666}
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000667
668#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000669/*
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000670 * On some systems poll() sets errno on invalid file descriptors. We test
671 * for this at runtime because this bug may be fixed or introduced between
672 * OS releases.
673 */
674static int select_have_broken_poll(void)
675{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000676 int poll_test;
677 int filedes[2];
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000678
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000679 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000680
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000681 /* Create a file descriptor to make invalid */
682 if (pipe(filedes) < 0) {
683 return 1;
684 }
685 poll_struct.fd = filedes[0];
686 close(filedes[0]);
687 close(filedes[1]);
688 poll_test = poll(&poll_struct, 1, 0);
689 if (poll_test < 0) {
690 return 1;
691 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
692 return 1;
693 }
694 return 0;
Ronald Oussoren32fd16e2006-04-23 12:36:23 +0000695}
696#endif /* __APPLE__ */
697
698#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000699
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000700#ifdef HAVE_EPOLL
701/* **************************************************************************
702 * epoll interface for Linux 2.6
703 *
704 * Written by Christian Heimes
705 * Inspired by Twisted's _epoll.pyx and select.poll()
706 */
707
708#ifdef HAVE_SYS_EPOLL_H
709#include <sys/epoll.h>
710#endif
711
712typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000713 PyObject_HEAD
714 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000715} pyEpoll_Object;
716
717static PyTypeObject pyEpoll_Type;
718#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
719
720static PyObject *
721pyepoll_err_closed(void)
722{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000723 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
724 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000725}
726
727static int
728pyepoll_internal_close(pyEpoll_Object *self)
729{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000730 int save_errno = 0;
731 if (self->epfd >= 0) {
732 int epfd = self->epfd;
733 self->epfd = -1;
734 Py_BEGIN_ALLOW_THREADS
735 if (close(epfd) < 0)
736 save_errno = errno;
737 Py_END_ALLOW_THREADS
738 }
739 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000740}
741
742static PyObject *
743newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
744{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000745 pyEpoll_Object *self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000746
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000747 if (sizehint == -1) {
748 sizehint = FD_SETSIZE-1;
749 }
750 else if (sizehint < 1) {
751 PyErr_Format(PyExc_ValueError,
752 "sizehint must be greater zero, got %d",
753 sizehint);
754 return NULL;
755 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000756
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000757 assert(type != NULL && type->tp_alloc != NULL);
758 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
759 if (self == NULL)
760 return NULL;
761
762 if (fd == -1) {
763 Py_BEGIN_ALLOW_THREADS
764 self->epfd = epoll_create(sizehint);
765 Py_END_ALLOW_THREADS
766 }
767 else {
768 self->epfd = fd;
769 }
770 if (self->epfd < 0) {
771 Py_DECREF(self);
772 PyErr_SetFromErrno(PyExc_IOError);
773 return NULL;
774 }
775 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000776}
777
778
779static PyObject *
780pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
781{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 int sizehint = -1;
783 static char *kwlist[] = {"sizehint", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000784
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000785 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
786 &sizehint))
787 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000788
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000789 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000790}
791
792
793static void
794pyepoll_dealloc(pyEpoll_Object *self)
795{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000796 (void)pyepoll_internal_close(self);
797 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000798}
799
800static PyObject*
801pyepoll_close(pyEpoll_Object *self)
802{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000803 errno = pyepoll_internal_close(self);
804 if (errno < 0) {
805 PyErr_SetFromErrno(PyExc_IOError);
806 return NULL;
807 }
808 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000809}
810
811PyDoc_STRVAR(pyepoll_close_doc,
812"close() -> None\n\
813\n\
814Close the epoll control file descriptor. Further operations on the epoll\n\
815object will raise an exception.");
816
817static PyObject*
818pyepoll_get_closed(pyEpoll_Object *self)
819{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000820 if (self->epfd < 0)
821 Py_RETURN_TRUE;
822 else
823 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000824}
825
826static PyObject*
827pyepoll_fileno(pyEpoll_Object *self)
828{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000829 if (self->epfd < 0)
830 return pyepoll_err_closed();
831 return PyInt_FromLong(self->epfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000832}
833
834PyDoc_STRVAR(pyepoll_fileno_doc,
835"fileno() -> int\n\
836\n\
837Return the epoll control file descriptor.");
838
839static PyObject*
840pyepoll_fromfd(PyObject *cls, PyObject *args)
841{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000842 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000843
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000844 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
845 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000846
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000847 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000848}
849
850PyDoc_STRVAR(pyepoll_fromfd_doc,
851"fromfd(fd) -> epoll\n\
852\n\
853Create an epoll object from a given control fd.");
854
855static PyObject *
856pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
857{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000858 struct epoll_event ev;
859 int result;
860 int fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000861
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 if (epfd < 0)
863 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000864
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000865 fd = PyObject_AsFileDescriptor(pfd);
866 if (fd == -1) {
867 return NULL;
868 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000869
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000870 switch(op) {
871 case EPOLL_CTL_ADD:
872 case EPOLL_CTL_MOD:
873 ev.events = events;
874 ev.data.fd = fd;
875 Py_BEGIN_ALLOW_THREADS
876 result = epoll_ctl(epfd, op, fd, &ev);
877 Py_END_ALLOW_THREADS
878 break;
879 case EPOLL_CTL_DEL:
880 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
881 * operation required a non-NULL pointer in event, even
882 * though this argument is ignored. */
883 Py_BEGIN_ALLOW_THREADS
884 result = epoll_ctl(epfd, op, fd, &ev);
885 if (errno == EBADF) {
886 /* fd already closed */
887 result = 0;
888 errno = 0;
889 }
890 Py_END_ALLOW_THREADS
891 break;
892 default:
893 result = -1;
894 errno = EINVAL;
895 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000896
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000897 if (result < 0) {
898 PyErr_SetFromErrno(PyExc_IOError);
899 return NULL;
900 }
901 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000902}
903
904static PyObject *
905pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
906{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000907 PyObject *pfd;
908 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
909 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000910
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000911 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
912 &pfd, &events)) {
913 return NULL;
914 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000915
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000916 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000917}
918
919PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl7d4bfb32010-08-02 21:44:25 +0000920"register(fd[, eventmask]) -> None\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000921\n\
Senthil Kumaran2bd91002011-06-26 23:50:35 -0700922Registers a new fd or raises an IOError if the fd is already registered.\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +0000923fd is the target file descriptor of the operation.\n\
924events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000925is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
926\n\
927The epoll interface supports all file descriptors that support poll.");
928
929static PyObject *
930pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
931{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000932 PyObject *pfd;
933 unsigned int events;
934 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000935
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000936 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
937 &pfd, &events)) {
938 return NULL;
939 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000940
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000941 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000942}
943
944PyDoc_STRVAR(pyepoll_modify_doc,
945"modify(fd, eventmask) -> None\n\
946\n\
947fd is the target file descriptor of the operation\n\
948events is a bit set composed of the various EPOLL constants");
949
950static PyObject *
951pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
952{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000953 PyObject *pfd;
954 static char *kwlist[] = {"fd", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000955
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000956 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
957 &pfd)) {
958 return NULL;
959 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000960
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000961 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000962}
963
964PyDoc_STRVAR(pyepoll_unregister_doc,
965"unregister(fd) -> None\n\
966\n\
967fd is the target file descriptor of the operation.");
968
969static PyObject *
970pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
971{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000972 double dtimeout = -1.;
973 int timeout;
974 int maxevents = -1;
975 int nfds, i;
976 PyObject *elist = NULL, *etuple = NULL;
977 struct epoll_event *evs = NULL;
978 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000979
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000980 if (self->epfd < 0)
981 return pyepoll_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000982
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000983 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
984 &dtimeout, &maxevents)) {
985 return NULL;
986 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000987
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000988 if (dtimeout < 0) {
989 timeout = -1;
990 }
991 else if (dtimeout * 1000.0 > INT_MAX) {
992 PyErr_SetString(PyExc_OverflowError,
993 "timeout is too large");
994 return NULL;
995 }
996 else {
997 timeout = (int)(dtimeout * 1000.0);
998 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +0000999
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001000 if (maxevents == -1) {
1001 maxevents = FD_SETSIZE-1;
1002 }
1003 else if (maxevents < 1) {
1004 PyErr_Format(PyExc_ValueError,
1005 "maxevents must be greater than 0, got %d",
1006 maxevents);
1007 return NULL;
1008 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001009
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001010 evs = PyMem_New(struct epoll_event, maxevents);
1011 if (evs == NULL) {
1012 Py_DECREF(self);
1013 PyErr_NoMemory();
1014 return NULL;
1015 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001016
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001017 Py_BEGIN_ALLOW_THREADS
1018 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1019 Py_END_ALLOW_THREADS
1020 if (nfds < 0) {
1021 PyErr_SetFromErrno(PyExc_IOError);
1022 goto error;
1023 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001024
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001025 elist = PyList_New(nfds);
1026 if (elist == NULL) {
1027 goto error;
1028 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001029
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001030 for (i = 0; i < nfds; i++) {
1031 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1032 if (etuple == NULL) {
1033 Py_CLEAR(elist);
1034 goto error;
1035 }
1036 PyList_SET_ITEM(elist, i, etuple);
1037 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001038
Georg Brandl018a3622008-03-26 12:57:47 +00001039 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001040 PyMem_Free(evs);
1041 return elist;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001042}
1043
1044PyDoc_STRVAR(pyepoll_poll_doc,
1045"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1046\n\
1047Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1048in seconds (as float). -1 makes poll wait indefinitely.\n\
1049Up to maxevents are returned to the caller.");
1050
1051static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001052 {"fromfd", (PyCFunction)pyepoll_fromfd,
1053 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1054 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1055 pyepoll_close_doc},
1056 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1057 pyepoll_fileno_doc},
1058 {"modify", (PyCFunction)pyepoll_modify,
1059 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1060 {"register", (PyCFunction)pyepoll_register,
1061 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1062 {"unregister", (PyCFunction)pyepoll_unregister,
1063 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1064 {"poll", (PyCFunction)pyepoll_poll,
1065 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1066 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001067};
1068
1069static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001070 {"closed", (getter)pyepoll_get_closed, NULL,
1071 "True if the epoll handler is closed"},
1072 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001073};
1074
1075PyDoc_STRVAR(pyepoll_doc,
1076"select.epoll([sizehint=-1])\n\
1077\n\
1078Returns an epolling object\n\
1079\n\
1080sizehint must be a positive integer or -1 for the default size. The\n\
1081sizehint is used to optimize internal data structures. It doesn't limit\n\
1082the maximum number of monitored events.");
1083
1084static PyTypeObject pyEpoll_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001085 PyVarObject_HEAD_INIT(NULL, 0)
1086 "select.epoll", /* tp_name */
1087 sizeof(pyEpoll_Object), /* tp_basicsize */
1088 0, /* tp_itemsize */
1089 (destructor)pyepoll_dealloc, /* tp_dealloc */
1090 0, /* tp_print */
1091 0, /* tp_getattr */
1092 0, /* tp_setattr */
1093 0, /* tp_compare */
1094 0, /* tp_repr */
1095 0, /* tp_as_number */
1096 0, /* tp_as_sequence */
1097 0, /* tp_as_mapping */
1098 0, /* tp_hash */
1099 0, /* tp_call */
1100 0, /* tp_str */
1101 PyObject_GenericGetAttr, /* tp_getattro */
1102 0, /* tp_setattro */
1103 0, /* tp_as_buffer */
1104 Py_TPFLAGS_DEFAULT, /* tp_flags */
1105 pyepoll_doc, /* tp_doc */
1106 0, /* tp_traverse */
1107 0, /* tp_clear */
1108 0, /* tp_richcompare */
1109 0, /* tp_weaklistoffset */
1110 0, /* tp_iter */
1111 0, /* tp_iternext */
1112 pyepoll_methods, /* tp_methods */
1113 0, /* tp_members */
1114 pyepoll_getsetlist, /* tp_getset */
1115 0, /* tp_base */
1116 0, /* tp_dict */
1117 0, /* tp_descr_get */
1118 0, /* tp_descr_set */
1119 0, /* tp_dictoffset */
1120 0, /* tp_init */
1121 0, /* tp_alloc */
1122 pyepoll_new, /* tp_new */
1123 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001124};
1125
1126#endif /* HAVE_EPOLL */
1127
1128#ifdef HAVE_KQUEUE
1129/* **************************************************************************
1130 * kqueue interface for BSD
1131 *
1132 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1133 * All rights reserved.
1134 *
1135 * Redistribution and use in source and binary forms, with or without
1136 * modification, are permitted provided that the following conditions
1137 * are met:
1138 * 1. Redistributions of source code must retain the above copyright
1139 * notice, this list of conditions and the following disclaimer.
1140 * 2. Redistributions in binary form must reproduce the above copyright
1141 * notice, this list of conditions and the following disclaimer in the
1142 * documentation and/or other materials provided with the distribution.
1143 *
1144 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1145 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1146 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1147 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1148 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1149 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1150 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1151 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1152 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1153 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1154 * SUCH DAMAGE.
1155 */
1156
1157#ifdef HAVE_SYS_EVENT_H
1158#include <sys/event.h>
1159#endif
1160
1161PyDoc_STRVAR(kqueue_event_doc,
Georg Brandlfa1ffb62009-12-29 21:09:17 +00001162"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001163\n\
1164This object is the equivalent of the struct kevent for the C API.\n\
1165\n\
1166See the kqueue manpage for more detailed information about the meaning\n\
1167of the arguments.\n\
1168\n\
1169One minor note: while you might hope that udata could store a\n\
1170reference to a python object, it cannot, because it is impossible to\n\
1171keep a proper reference count of the object once it's passed into the\n\
1172kernel. Therefore, I have restricted it to only storing an integer. I\n\
1173recommend ignoring it and simply using the 'ident' field to key off\n\
1174of. You could also set up a dictionary on the python side to store a\n\
1175udata->object mapping.");
1176
1177typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001178 PyObject_HEAD
1179 struct kevent e;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001180} kqueue_event_Object;
1181
1182static PyTypeObject kqueue_event_Type;
1183
1184#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1185
1186typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001187 PyObject_HEAD
1188 SOCKET kqfd; /* kqueue control fd */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001189} kqueue_queue_Object;
1190
1191static PyTypeObject kqueue_queue_Type;
1192
1193#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1194
Antoine Pitrou323b9da2009-11-04 19:25:14 +00001195#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1196# error uintptr_t does not match void *!
1197#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1198# define T_UINTPTRT T_ULONGLONG
1199# define T_INTPTRT T_LONGLONG
1200# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1201# define UINTPTRT_FMT_UNIT "K"
1202# define INTPTRT_FMT_UNIT "L"
1203#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1204# define T_UINTPTRT T_ULONG
1205# define T_INTPTRT T_LONG
1206# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1207# define UINTPTRT_FMT_UNIT "k"
1208# define INTPTRT_FMT_UNIT "l"
1209#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1210# define T_UINTPTRT T_UINT
1211# define T_INTPTRT T_INT
1212# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1213# define UINTPTRT_FMT_UNIT "I"
1214# define INTPTRT_FMT_UNIT "i"
1215#else
1216# error uintptr_t does not match int, long, or long long!
1217#endif
1218
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001219/*
1220 * kevent is not standard and its members vary across BSDs.
1221 */
1222#if !defined(__OpenBSD__)
1223# define IDENT_TYPE T_UINTPTRT
1224# define IDENT_CAST Py_intptr_t
1225# define DATA_TYPE T_INTPTRT
1226# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1227# define IDENT_AsType PyLong_AsUintptr_t
1228#else
1229# define IDENT_TYPE T_UINT
1230# define IDENT_CAST int
1231# define DATA_TYPE T_INT
1232# define DATA_FMT_UNIT "i"
1233# define IDENT_AsType PyLong_AsUnsignedLong
1234#endif
1235
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001236/* Unfortunately, we can't store python objects in udata, because
1237 * kevents in the kernel can be removed without warning, which would
1238 * forever lose the refcount on the object stored with it.
1239 */
1240
1241#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1242static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001243 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001244 {"filter", T_SHORT, KQ_OFF(e.filter)},
1245 {"flags", T_USHORT, KQ_OFF(e.flags)},
1246 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001247 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001248 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1249 {NULL} /* Sentinel */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001250};
1251#undef KQ_OFF
1252
1253static PyObject *
Georg Brandlea370a92010-02-23 21:48:57 +00001254
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001255kqueue_event_repr(kqueue_event_Object *s)
1256{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001257 char buf[1024];
1258 PyOS_snprintf(
1259 buf, sizeof(buf),
1260 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1261 "data=0x%zd udata=%p>",
1262 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1263 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1264 return PyString_FromString(buf);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001265}
1266
1267static int
1268kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1269{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001270 PyObject *pfd;
1271 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1272 "data", "udata", NULL};
Christian Heimes42831fe2013-08-25 14:57:00 +02001273 static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001274
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001275 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001276
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001277 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1278 &pfd, &(self->e.filter), &(self->e.flags),
1279 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1280 return -1;
1281 }
1282
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001283 if (PyLong_Check(pfd)
1284#if IDENT_TYPE == T_UINT
1285 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1286#endif
1287 ) {
1288 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001289 }
1290 else {
1291 self->e.ident = PyObject_AsFileDescriptor(pfd);
1292 }
1293 if (PyErr_Occurred()) {
1294 return -1;
1295 }
1296 return 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001297}
1298
1299static PyObject *
1300kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001301 int op)
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001302{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001303 Py_intptr_t result = 0;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001304
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001305 if (!kqueue_event_Check(o)) {
1306 if (op == Py_EQ || op == Py_NE) {
1307 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1308 Py_INCREF(res);
1309 return res;
1310 }
1311 PyErr_Format(PyExc_TypeError,
1312 "can't compare %.200s to %.200s",
1313 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1314 return NULL;
1315 }
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001316 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001317 ((result = s->e.filter - o->e.filter) == 0) &&
1318 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali880359c2013-05-06 21:21:57 +02001319 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001320 ((result = s->e.data - o->e.data) == 0) &&
1321 ((result = s->e.udata - o->e.udata) == 0)
1322 ) {
1323 result = 0;
1324 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001325
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001326 switch (op) {
1327 case Py_EQ:
1328 result = (result == 0);
1329 break;
1330 case Py_NE:
1331 result = (result != 0);
1332 break;
1333 case Py_LE:
1334 result = (result <= 0);
1335 break;
1336 case Py_GE:
1337 result = (result >= 0);
1338 break;
1339 case Py_LT:
1340 result = (result < 0);
1341 break;
1342 case Py_GT:
1343 result = (result > 0);
1344 break;
1345 }
1346 return PyBool_FromLong((long)result);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001347}
1348
1349static PyTypeObject kqueue_event_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001350 PyVarObject_HEAD_INIT(NULL, 0)
1351 "select.kevent", /* tp_name */
1352 sizeof(kqueue_event_Object), /* tp_basicsize */
1353 0, /* tp_itemsize */
1354 0, /* tp_dealloc */
1355 0, /* tp_print */
1356 0, /* tp_getattr */
1357 0, /* tp_setattr */
1358 0, /* tp_compare */
1359 (reprfunc)kqueue_event_repr, /* tp_repr */
1360 0, /* tp_as_number */
1361 0, /* tp_as_sequence */
1362 0, /* tp_as_mapping */
1363 0, /* tp_hash */
1364 0, /* tp_call */
1365 0, /* tp_str */
1366 0, /* tp_getattro */
1367 0, /* tp_setattro */
1368 0, /* tp_as_buffer */
1369 Py_TPFLAGS_DEFAULT, /* tp_flags */
1370 kqueue_event_doc, /* tp_doc */
1371 0, /* tp_traverse */
1372 0, /* tp_clear */
1373 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1374 0, /* tp_weaklistoffset */
1375 0, /* tp_iter */
1376 0, /* tp_iternext */
1377 0, /* tp_methods */
1378 kqueue_event_members, /* tp_members */
1379 0, /* tp_getset */
1380 0, /* tp_base */
1381 0, /* tp_dict */
1382 0, /* tp_descr_get */
1383 0, /* tp_descr_set */
1384 0, /* tp_dictoffset */
1385 (initproc)kqueue_event_init, /* tp_init */
1386 0, /* tp_alloc */
1387 0, /* tp_new */
1388 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001389};
1390
1391static PyObject *
1392kqueue_queue_err_closed(void)
1393{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001394 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1395 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001396}
1397
1398static int
1399kqueue_queue_internal_close(kqueue_queue_Object *self)
1400{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001401 int save_errno = 0;
1402 if (self->kqfd >= 0) {
1403 int kqfd = self->kqfd;
1404 self->kqfd = -1;
1405 Py_BEGIN_ALLOW_THREADS
1406 if (close(kqfd) < 0)
1407 save_errno = errno;
1408 Py_END_ALLOW_THREADS
1409 }
1410 return save_errno;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001411}
1412
1413static PyObject *
1414newKqueue_Object(PyTypeObject *type, SOCKET fd)
1415{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001416 kqueue_queue_Object *self;
1417 assert(type != NULL && type->tp_alloc != NULL);
1418 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1419 if (self == NULL) {
1420 return NULL;
1421 }
1422
1423 if (fd == -1) {
1424 Py_BEGIN_ALLOW_THREADS
1425 self->kqfd = kqueue();
1426 Py_END_ALLOW_THREADS
1427 }
1428 else {
1429 self->kqfd = fd;
1430 }
1431 if (self->kqfd < 0) {
1432 Py_DECREF(self);
1433 PyErr_SetFromErrno(PyExc_IOError);
1434 return NULL;
1435 }
1436 return (PyObject *)self;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001437}
1438
1439static PyObject *
1440kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1441{
1442
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001443 if ((args != NULL && PyObject_Size(args)) ||
1444 (kwds != NULL && PyObject_Size(kwds))) {
1445 PyErr_SetString(PyExc_ValueError,
1446 "select.kqueue doesn't accept arguments");
1447 return NULL;
1448 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001449
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001450 return newKqueue_Object(type, -1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001451}
1452
1453static void
1454kqueue_queue_dealloc(kqueue_queue_Object *self)
1455{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001456 kqueue_queue_internal_close(self);
1457 Py_TYPE(self)->tp_free(self);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001458}
1459
1460static PyObject*
1461kqueue_queue_close(kqueue_queue_Object *self)
1462{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001463 errno = kqueue_queue_internal_close(self);
1464 if (errno < 0) {
1465 PyErr_SetFromErrno(PyExc_IOError);
1466 return NULL;
1467 }
1468 Py_RETURN_NONE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001469}
1470
1471PyDoc_STRVAR(kqueue_queue_close_doc,
1472"close() -> None\n\
1473\n\
1474Close the kqueue control file descriptor. Further operations on the kqueue\n\
1475object will raise an exception.");
1476
1477static PyObject*
1478kqueue_queue_get_closed(kqueue_queue_Object *self)
1479{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001480 if (self->kqfd < 0)
1481 Py_RETURN_TRUE;
1482 else
1483 Py_RETURN_FALSE;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001484}
1485
1486static PyObject*
1487kqueue_queue_fileno(kqueue_queue_Object *self)
1488{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001489 if (self->kqfd < 0)
1490 return kqueue_queue_err_closed();
1491 return PyInt_FromLong(self->kqfd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001492}
1493
1494PyDoc_STRVAR(kqueue_queue_fileno_doc,
1495"fileno() -> int\n\
1496\n\
1497Return the kqueue control file descriptor.");
1498
1499static PyObject*
1500kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1501{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001502 SOCKET fd;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001503
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001504 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1505 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001506
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001507 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001508}
1509
1510PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1511"fromfd(fd) -> kqueue\n\
1512\n\
1513Create a kqueue object from a given control fd.");
1514
1515static PyObject *
1516kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1517{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001518 int nevents = 0;
1519 int gotevents = 0;
1520 int nchanges = 0;
1521 int i = 0;
1522 PyObject *otimeout = NULL;
1523 PyObject *ch = NULL;
1524 PyObject *it = NULL, *ei = NULL;
1525 PyObject *result = NULL;
1526 struct kevent *evl = NULL;
1527 struct kevent *chl = NULL;
1528 struct timespec timeoutspec;
1529 struct timespec *ptimeoutspec;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001530
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001531 if (self->kqfd < 0)
1532 return kqueue_queue_err_closed();
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001533
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001534 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1535 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001536
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001537 if (nevents < 0) {
1538 PyErr_Format(PyExc_ValueError,
1539 "Length of eventlist must be 0 or positive, got %d",
1540 nevents);
1541 return NULL;
1542 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001543
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001544 if (otimeout == Py_None || otimeout == NULL) {
1545 ptimeoutspec = NULL;
1546 }
1547 else if (PyNumber_Check(otimeout)) {
1548 double timeout;
1549 long seconds;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001550
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001551 timeout = PyFloat_AsDouble(otimeout);
1552 if (timeout == -1 && PyErr_Occurred())
1553 return NULL;
1554 if (timeout > (double)LONG_MAX) {
1555 PyErr_SetString(PyExc_OverflowError,
1556 "timeout period too long");
1557 return NULL;
1558 }
1559 if (timeout < 0) {
1560 PyErr_SetString(PyExc_ValueError,
1561 "timeout must be positive or None");
1562 return NULL;
1563 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001564
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001565 seconds = (long)timeout;
1566 timeout = timeout - (double)seconds;
1567 timeoutspec.tv_sec = seconds;
1568 timeoutspec.tv_nsec = (long)(timeout * 1E9);
1569 ptimeoutspec = &timeoutspec;
1570 }
1571 else {
1572 PyErr_Format(PyExc_TypeError,
1573 "timeout argument must be an number "
1574 "or None, got %.200s",
1575 Py_TYPE(otimeout)->tp_name);
1576 return NULL;
1577 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001578
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001579 if (ch != NULL && ch != Py_None) {
1580 it = PyObject_GetIter(ch);
1581 if (it == NULL) {
1582 PyErr_SetString(PyExc_TypeError,
1583 "changelist is not iterable");
1584 return NULL;
1585 }
1586 nchanges = PyObject_Size(ch);
1587 if (nchanges < 0) {
1588 goto error;
1589 }
Georg Brandlea370a92010-02-23 21:48:57 +00001590
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001591 chl = PyMem_New(struct kevent, nchanges);
1592 if (chl == NULL) {
1593 PyErr_NoMemory();
1594 goto error;
1595 }
1596 i = 0;
1597 while ((ei = PyIter_Next(it)) != NULL) {
1598 if (!kqueue_event_Check(ei)) {
1599 Py_DECREF(ei);
1600 PyErr_SetString(PyExc_TypeError,
1601 "changelist must be an iterable of "
1602 "select.kevent objects");
1603 goto error;
1604 } else {
1605 chl[i++] = ((kqueue_event_Object *)ei)->e;
1606 }
1607 Py_DECREF(ei);
1608 }
1609 }
1610 Py_CLEAR(it);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001611
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001612 /* event list */
1613 if (nevents) {
1614 evl = PyMem_New(struct kevent, nevents);
1615 if (evl == NULL) {
1616 PyErr_NoMemory();
1617 goto error;
1618 }
1619 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001620
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001621 Py_BEGIN_ALLOW_THREADS
1622 gotevents = kevent(self->kqfd, chl, nchanges,
1623 evl, nevents, ptimeoutspec);
1624 Py_END_ALLOW_THREADS
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001625
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001626 if (gotevents == -1) {
1627 PyErr_SetFromErrno(PyExc_OSError);
1628 goto error;
1629 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001630
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001631 result = PyList_New(gotevents);
1632 if (result == NULL) {
1633 goto error;
1634 }
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001635
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001636 for (i = 0; i < gotevents; i++) {
1637 kqueue_event_Object *ch;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001638
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001639 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1640 if (ch == NULL) {
1641 goto error;
1642 }
1643 ch->e = evl[i];
1644 PyList_SET_ITEM(result, i, (PyObject *)ch);
1645 }
1646 PyMem_Free(chl);
1647 PyMem_Free(evl);
1648 return result;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001649
1650 error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001651 PyMem_Free(chl);
1652 PyMem_Free(evl);
1653 Py_XDECREF(result);
1654 Py_XDECREF(it);
1655 return NULL;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001656}
1657
1658PyDoc_STRVAR(kqueue_queue_control_doc,
Georg Brandl2f3bd832008-09-21 07:14:44 +00001659"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001660\n\
1661Calls the kernel kevent function.\n\
1662- changelist must be a list of kevent objects describing the changes\n\
1663 to be made to the kernel's watch list or None.\n\
1664- max_events lets you specify the maximum number of events that the\n\
1665 kernel will return.\n\
1666- timeout is the maximum time to wait in seconds, or else None,\n\
1667 to wait forever. timeout accepts floats for smaller timeouts, too.");
1668
1669
1670static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001671 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
1672 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1673 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1674 kqueue_queue_close_doc},
1675 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1676 kqueue_queue_fileno_doc},
1677 {"control", (PyCFunction)kqueue_queue_control,
1678 METH_VARARGS , kqueue_queue_control_doc},
1679 {NULL, NULL},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001680};
1681
1682static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001683 {"closed", (getter)kqueue_queue_get_closed, NULL,
1684 "True if the kqueue handler is closed"},
1685 {0},
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001686};
1687
1688PyDoc_STRVAR(kqueue_queue_doc,
1689"Kqueue syscall wrapper.\n\
1690\n\
1691For example, to start watching a socket for input:\n\
1692>>> kq = kqueue()\n\
1693>>> sock = socket()\n\
1694>>> sock.connect((host, port))\n\
1695>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1696\n\
1697To wait one second for it to become writeable:\n\
1698>>> kq.control(None, 1, 1000)\n\
1699\n\
1700To stop listening:\n\
1701>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1702
1703static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001704 PyVarObject_HEAD_INIT(NULL, 0)
1705 "select.kqueue", /* tp_name */
1706 sizeof(kqueue_queue_Object), /* tp_basicsize */
1707 0, /* tp_itemsize */
1708 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
1709 0, /* tp_print */
1710 0, /* tp_getattr */
1711 0, /* tp_setattr */
1712 0, /* tp_compare */
1713 0, /* tp_repr */
1714 0, /* tp_as_number */
1715 0, /* tp_as_sequence */
1716 0, /* tp_as_mapping */
1717 0, /* tp_hash */
1718 0, /* tp_call */
1719 0, /* tp_str */
1720 0, /* tp_getattro */
1721 0, /* tp_setattro */
1722 0, /* tp_as_buffer */
1723 Py_TPFLAGS_DEFAULT, /* tp_flags */
1724 kqueue_queue_doc, /* tp_doc */
1725 0, /* tp_traverse */
1726 0, /* tp_clear */
1727 0, /* tp_richcompare */
1728 0, /* tp_weaklistoffset */
1729 0, /* tp_iter */
1730 0, /* tp_iternext */
1731 kqueue_queue_methods, /* tp_methods */
1732 0, /* tp_members */
1733 kqueue_queue_getsetlist, /* tp_getset */
1734 0, /* tp_base */
1735 0, /* tp_dict */
1736 0, /* tp_descr_get */
1737 0, /* tp_descr_set */
1738 0, /* tp_dictoffset */
1739 0, /* tp_init */
1740 0, /* tp_alloc */
1741 kqueue_queue_new, /* tp_new */
1742 0, /* tp_free */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001743};
1744
1745#endif /* HAVE_KQUEUE */
1746/* ************************************************************************ */
1747
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001748PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001749"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1750\n\
1751Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00001752The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001753rlist -- wait until ready for reading\n\
1754wlist -- wait until ready for writing\n\
1755xlist -- wait for an ``exceptional condition''\n\
1756If only one kind of condition is required, pass [] for the other lists.\n\
1757A file descriptor is either a socket or file object, or a small integer\n\
1758gotten from a fileno() method call on one of those.\n\
1759\n\
1760The optional 4th argument specifies a timeout in seconds; it may be\n\
1761a floating point number to specify fractions of seconds. If it is absent\n\
1762or None, the call will never time out.\n\
1763\n\
1764The return value is a tuple of three lists corresponding to the first three\n\
1765arguments; each contains the subset of the corresponding file descriptors\n\
1766that are ready.\n\
1767\n\
1768*** IMPORTANT NOTICE ***\n\
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001769On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
Andrew M. Kuchlinga8c3f2b2008-03-26 00:16:50 +00001770descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001771
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00001772static PyMethodDef select_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001773 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natalia41cf292013-01-19 12:15:56 +01001774#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001775 {"poll", select_poll, METH_NOARGS, poll_doc},
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001776#endif /* HAVE_POLL */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001777 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00001778};
1779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001780PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00001781"This module supports asynchronous I/O on multiple file descriptors.\n\
1782\n\
1783*** IMPORTANT NOTICE ***\n\
Neal Norwitz2a30cd02006-07-10 01:18:57 +00001784On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00001785
Mark Hammond62b1ab12002-07-23 06:31:15 +00001786PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001787initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00001788{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001789 PyObject *m;
1790 m = Py_InitModule3("select", select_methods, module_doc);
1791 if (m == NULL)
1792 return;
Fred Drake4baedc12002-04-01 14:53:37 +00001793
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001794 SelectError = PyErr_NewException("select.error", NULL, NULL);
1795 Py_INCREF(SelectError);
1796 PyModule_AddObject(m, "error", SelectError);
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001797
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001798#ifdef PIPE_BUF
R. David Murray1d9d16e2010-10-16 00:43:13 +00001799#ifdef HAVE_BROKEN_PIPE_BUF
1800#undef PIPE_BUF
1801#define PIPE_BUF 512
1802#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001803 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
Amaury Forgeot d'Arcce32eb72009-07-09 22:37:22 +00001804#endif
Gregory P. Smith9d36fd22009-07-03 20:48:31 +00001805
Charles-François Natalia41cf292013-01-19 12:15:56 +01001806#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001807#ifdef __APPLE__
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001808 if (select_have_broken_poll()) {
1809 if (PyObject_DelAttrString(m, "poll") == -1) {
1810 PyErr_Clear();
1811 }
1812 } else {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001813#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001814 {
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001815#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001816 Py_TYPE(&poll_Type) = &PyType_Type;
1817 PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1818 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1819 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1820 PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1821 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1822 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001823
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001824#ifdef POLLRDNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001825 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001826#endif
1827#ifdef POLLRDBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001828 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001829#endif
1830#ifdef POLLWRNORM
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001831 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001832#endif
1833#ifdef POLLWRBAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001834 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00001835#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001836#ifdef POLLMSG
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001837 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00001838#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001839 }
Ronald Oussoren32fd16e2006-04-23 12:36:23 +00001840#endif /* HAVE_POLL */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001841
1842#ifdef HAVE_EPOLL
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001843 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1844 if (PyType_Ready(&pyEpoll_Type) < 0)
1845 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001846
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001847 Py_INCREF(&pyEpoll_Type);
1848 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001849
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001850 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1851 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1852 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1853 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1854 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1855 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001856#ifdef EPOLLONESHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001857 /* Kernel 2.6.2+ */
1858 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001859#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001860 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1861 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1862 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1863 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1864 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1865 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001866#endif /* HAVE_EPOLL */
1867
1868#ifdef HAVE_KQUEUE
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001869 kqueue_event_Type.tp_new = PyType_GenericNew;
1870 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1871 if(PyType_Ready(&kqueue_event_Type) < 0)
1872 return;
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001873
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001874 Py_INCREF(&kqueue_event_Type);
1875 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001876
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001877 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1878 if(PyType_Ready(&kqueue_queue_Type) < 0)
1879 return;
1880 Py_INCREF(&kqueue_queue_Type);
1881 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1882
1883 /* event filters */
1884 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1885 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1886 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1887 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1888 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001889#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001890 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001891#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001892 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1893 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001894
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001895 /* event flags */
1896 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1897 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1898 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1899 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1900 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1901 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001902
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001903 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1904 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001905
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001906 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1907 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001908
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001909 /* READ WRITE filter flag */
1910 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001911
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001912 /* VNODE filter flags */
1913 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1914 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1915 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1916 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1917 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1918 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1919 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001920
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001921 /* PROC filter flags */
1922 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1923 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1924 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1925 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1926 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001927
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001928 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1929 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1930 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1931
1932 /* NETDEV filter flags */
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001933#ifdef EVFILT_NETDEV
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001934 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1935 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1936 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes0e9ab5f2008-03-21 23:49:44 +00001937#endif
1938
1939#endif /* HAVE_KQUEUE */
Guido van Rossumed233a51992-06-23 09:07:03 +00001940}