• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* select - Module containing unix select(2) call.
2    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.
5 */
6 
7 #if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
8 #define _GNU_SOURCE
9 #endif
10 
11 #include "Python.h"
12 #include <structmember.h>
13 
14 #ifdef HAVE_SYS_DEVPOLL_H
15 #include <sys/resource.h>
16 #include <sys/devpoll.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #endif
21 
22 #ifdef __APPLE__
23     /* Perform runtime testing for a broken poll on OSX to make it easier
24      * to use the same binary on multiple releases of the OS.
25      */
26 #undef HAVE_BROKEN_POLL
27 #endif
28 
29 /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
30    64 is too small (too many people have bumped into that limit).
31    Here we boost it.
32    Users who want even more than the boosted limit should #define
33    FD_SETSIZE higher before this; e.g., via compiler /D switch.
34 */
35 #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
36 #define FD_SETSIZE 512
37 #endif
38 
39 #if defined(HAVE_POLL_H)
40 #include <poll.h>
41 #elif defined(HAVE_SYS_POLL_H)
42 #include <sys/poll.h>
43 #endif
44 
45 #ifdef __sgi
46 /* This is missing from unistd.h */
47 extern void bzero(void *, int);
48 #endif
49 
50 #ifdef HAVE_SYS_TYPES_H
51 #include <sys/types.h>
52 #endif
53 
54 #ifdef MS_WINDOWS
55 #  define WIN32_LEAN_AND_MEAN
56 #  include <winsock.h>
57 #else
58 #  define SOCKET int
59 #endif
60 
61 /* list of Python objects and their file descriptor */
62 typedef struct {
63     PyObject *obj;                           /* owned reference */
64     SOCKET fd;
65     int sentinel;                            /* -1 == sentinel */
66 } pylist;
67 
68 static void
reap_obj(pylist fd2obj[FD_SETSIZE+1])69 reap_obj(pylist fd2obj[FD_SETSIZE + 1])
70 {
71     int i;
72     for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
73         Py_CLEAR(fd2obj[i].obj);
74     }
75     fd2obj[0].sentinel = -1;
76 }
77 
78 
79 /* returns -1 and sets the Python exception if an error occurred, otherwise
80    returns a number >= 0
81 */
82 static int
seq2set(PyObject * seq,fd_set * set,pylist fd2obj[FD_SETSIZE+1])83 seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
84 {
85     int max = -1;
86     int index = 0;
87     Py_ssize_t i;
88     PyObject* fast_seq = NULL;
89     PyObject* o = NULL;
90 
91     fd2obj[0].obj = (PyObject*)0;            /* set list to zero size */
92     FD_ZERO(set);
93 
94     fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
95     if (!fast_seq)
96         return -1;
97 
98     for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++)  {
99         SOCKET v;
100 
101         /* any intervening fileno() calls could decr this refcnt */
102         if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
103             goto finally;
104 
105         Py_INCREF(o);
106         v = PyObject_AsFileDescriptor( o );
107         if (v == -1) goto finally;
108 
109 #if defined(_MSC_VER)
110         max = 0;                             /* not used for Win32 */
111 #else  /* !_MSC_VER */
112         if (!_PyIsSelectable_fd(v)) {
113             PyErr_SetString(PyExc_ValueError,
114                         "filedescriptor out of range in select()");
115             goto finally;
116         }
117         if (v > max)
118             max = v;
119 #endif /* _MSC_VER */
120         FD_SET(v, set);
121 
122         /* add object and its file descriptor to the list */
123         if (index >= FD_SETSIZE) {
124             PyErr_SetString(PyExc_ValueError,
125                           "too many file descriptors in select()");
126             goto finally;
127         }
128         fd2obj[index].obj = o;
129         fd2obj[index].fd = v;
130         fd2obj[index].sentinel = 0;
131         fd2obj[++index].sentinel = -1;
132     }
133     Py_DECREF(fast_seq);
134     return max+1;
135 
136   finally:
137     Py_XDECREF(o);
138     Py_DECREF(fast_seq);
139     return -1;
140 }
141 
142 /* returns NULL and sets the Python exception if an error occurred */
143 static PyObject *
set2list(fd_set * set,pylist fd2obj[FD_SETSIZE+1])144 set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
145 {
146     int i, j, count=0;
147     PyObject *list, *o;
148     SOCKET fd;
149 
150     for (j = 0; fd2obj[j].sentinel >= 0; j++) {
151         if (FD_ISSET(fd2obj[j].fd, set))
152             count++;
153     }
154     list = PyList_New(count);
155     if (!list)
156         return NULL;
157 
158     i = 0;
159     for (j = 0; fd2obj[j].sentinel >= 0; j++) {
160         fd = fd2obj[j].fd;
161         if (FD_ISSET(fd, set)) {
162             o = fd2obj[j].obj;
163             fd2obj[j].obj = NULL;
164             /* transfer ownership */
165             if (PyList_SetItem(list, i, o) < 0)
166                 goto finally;
167 
168             i++;
169         }
170     }
171     return list;
172   finally:
173     Py_DECREF(list);
174     return NULL;
175 }
176 
177 #undef SELECT_USES_HEAP
178 #if FD_SETSIZE > 1024
179 #define SELECT_USES_HEAP
180 #endif /* FD_SETSIZE > 1024 */
181 
182 static PyObject *
select_select(PyObject * self,PyObject * args)183 select_select(PyObject *self, PyObject *args)
184 {
185 #ifdef SELECT_USES_HEAP
186     pylist *rfd2obj, *wfd2obj, *efd2obj;
187 #else  /* !SELECT_USES_HEAP */
188     /* XXX: All this should probably be implemented as follows:
189      * - find the highest descriptor we're interested in
190      * - add one
191      * - that's the size
192      * See: Stevens, APitUE, $12.5.1
193      */
194     pylist rfd2obj[FD_SETSIZE + 1];
195     pylist wfd2obj[FD_SETSIZE + 1];
196     pylist efd2obj[FD_SETSIZE + 1];
197 #endif /* SELECT_USES_HEAP */
198     PyObject *ifdlist, *ofdlist, *efdlist;
199     PyObject *ret = NULL;
200     PyObject *timeout_obj = Py_None;
201     fd_set ifdset, ofdset, efdset;
202     struct timeval tv, *tvp;
203     int imax, omax, emax, max;
204     int n;
205     _PyTime_t timeout, deadline = 0;
206 
207     /* convert arguments */
208     if (!PyArg_UnpackTuple(args, "select", 3, 4,
209                           &ifdlist, &ofdlist, &efdlist, &timeout_obj))
210         return NULL;
211 
212     if (timeout_obj == Py_None)
213         tvp = (struct timeval *)NULL;
214     else {
215         if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
216                                       _PyTime_ROUND_CEILING) < 0) {
217             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
218                 PyErr_SetString(PyExc_TypeError,
219                                 "timeout must be a float or None");
220             }
221             return NULL;
222         }
223 
224         if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_CEILING) == -1)
225             return NULL;
226         if (tv.tv_sec < 0) {
227             PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
228             return NULL;
229         }
230         tvp = &tv;
231     }
232 
233 #ifdef SELECT_USES_HEAP
234     /* Allocate memory for the lists */
235     rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
236     wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
237     efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
238     if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
239         if (rfd2obj) PyMem_DEL(rfd2obj);
240         if (wfd2obj) PyMem_DEL(wfd2obj);
241         if (efd2obj) PyMem_DEL(efd2obj);
242         return PyErr_NoMemory();
243     }
244 #endif /* SELECT_USES_HEAP */
245 
246     /* Convert sequences to fd_sets, and get maximum fd number
247      * propagates the Python exception set in seq2set()
248      */
249     rfd2obj[0].sentinel = -1;
250     wfd2obj[0].sentinel = -1;
251     efd2obj[0].sentinel = -1;
252     if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
253         goto finally;
254     if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
255         goto finally;
256     if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
257         goto finally;
258 
259     max = imax;
260     if (omax > max) max = omax;
261     if (emax > max) max = emax;
262 
263     if (tvp)
264         deadline = _PyTime_GetMonotonicClock() + timeout;
265 
266     do {
267         Py_BEGIN_ALLOW_THREADS
268         errno = 0;
269         n = select(max, &ifdset, &ofdset, &efdset, tvp);
270         Py_END_ALLOW_THREADS
271 
272         if (errno != EINTR)
273             break;
274 
275         /* select() was interrupted by a signal */
276         if (PyErr_CheckSignals())
277             goto finally;
278 
279         if (tvp) {
280             timeout = deadline - _PyTime_GetMonotonicClock();
281             if (timeout < 0) {
282                 n = 0;
283                 break;
284             }
285             _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
286             /* retry select() with the recomputed timeout */
287         }
288     } while (1);
289 
290 #ifdef MS_WINDOWS
291     if (n == SOCKET_ERROR) {
292         PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
293     }
294 #else
295     if (n < 0) {
296         PyErr_SetFromErrno(PyExc_OSError);
297     }
298 #endif
299     else {
300         /* any of these three calls can raise an exception.  it's more
301            convenient to test for this after all three calls... but
302            is that acceptable?
303         */
304         ifdlist = set2list(&ifdset, rfd2obj);
305         ofdlist = set2list(&ofdset, wfd2obj);
306         efdlist = set2list(&efdset, efd2obj);
307         if (PyErr_Occurred())
308             ret = NULL;
309         else
310             ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
311 
312         Py_XDECREF(ifdlist);
313         Py_XDECREF(ofdlist);
314         Py_XDECREF(efdlist);
315     }
316 
317   finally:
318     reap_obj(rfd2obj);
319     reap_obj(wfd2obj);
320     reap_obj(efd2obj);
321 #ifdef SELECT_USES_HEAP
322     PyMem_DEL(rfd2obj);
323     PyMem_DEL(wfd2obj);
324     PyMem_DEL(efd2obj);
325 #endif /* SELECT_USES_HEAP */
326     return ret;
327 }
328 
329 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
330 /*
331  * poll() support
332  */
333 
334 typedef struct {
335     PyObject_HEAD
336     PyObject *dict;
337     int ufd_uptodate;
338     int ufd_len;
339     struct pollfd *ufds;
340     int poll_running;
341 } pollObject;
342 
343 static PyTypeObject poll_Type;
344 
345 /* Update the malloc'ed array of pollfds to match the dictionary
346    contained within a pollObject.  Return 1 on success, 0 on an error.
347 */
348 
349 static int
update_ufd_array(pollObject * self)350 update_ufd_array(pollObject *self)
351 {
352     Py_ssize_t i, pos;
353     PyObject *key, *value;
354     struct pollfd *old_ufds = self->ufds;
355 
356     self->ufd_len = PyDict_Size(self->dict);
357     PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
358     if (self->ufds == NULL) {
359         self->ufds = old_ufds;
360         PyErr_NoMemory();
361         return 0;
362     }
363 
364     i = pos = 0;
365     while (PyDict_Next(self->dict, &pos, &key, &value)) {
366         assert(i < self->ufd_len);
367         /* Never overflow */
368         self->ufds[i].fd = (int)PyLong_AsLong(key);
369         self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
370         i++;
371     }
372     assert(i == self->ufd_len);
373     self->ufd_uptodate = 1;
374     return 1;
375 }
376 
377 static int
ushort_converter(PyObject * obj,void * ptr)378 ushort_converter(PyObject *obj, void *ptr)
379 {
380     unsigned long uval;
381 
382     uval = PyLong_AsUnsignedLong(obj);
383     if (uval == (unsigned long)-1 && PyErr_Occurred())
384         return 0;
385     if (uval > USHRT_MAX) {
386         PyErr_SetString(PyExc_OverflowError,
387                         "Python int too large for C unsigned short");
388         return 0;
389     }
390 
391     *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
392     return 1;
393 }
394 
395 PyDoc_STRVAR(poll_register_doc,
396 "register(fd [, eventmask] ) -> None\n\n\
397 Register a file descriptor with the polling object.\n\
398 fd -- either an integer, or an object with a fileno() method returning an\n\
399       int.\n\
400 events -- an optional bitmask describing the type of events to check for");
401 
402 static PyObject *
poll_register(pollObject * self,PyObject * args)403 poll_register(pollObject *self, PyObject *args)
404 {
405     PyObject *o, *key, *value;
406     int fd;
407     unsigned short events = POLLIN | POLLPRI | POLLOUT;
408     int err;
409 
410     if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
411         return NULL;
412 
413     fd = PyObject_AsFileDescriptor(o);
414     if (fd == -1) return NULL;
415 
416     /* Add entry to the internal dictionary: the key is the
417        file descriptor, and the value is the event mask. */
418     key = PyLong_FromLong(fd);
419     if (key == NULL)
420         return NULL;
421     value = PyLong_FromLong(events);
422     if (value == NULL) {
423         Py_DECREF(key);
424         return NULL;
425     }
426     err = PyDict_SetItem(self->dict, key, value);
427     Py_DECREF(key);
428     Py_DECREF(value);
429     if (err < 0)
430         return NULL;
431 
432     self->ufd_uptodate = 0;
433 
434     Py_INCREF(Py_None);
435     return Py_None;
436 }
437 
438 PyDoc_STRVAR(poll_modify_doc,
439 "modify(fd, eventmask) -> None\n\n\
440 Modify an already registered file descriptor.\n\
441 fd -- either an integer, or an object with a fileno() method returning an\n\
442       int.\n\
443 events -- an optional bitmask describing the type of events to check for");
444 
445 static PyObject *
poll_modify(pollObject * self,PyObject * args)446 poll_modify(pollObject *self, PyObject *args)
447 {
448     PyObject *o, *key, *value;
449     int fd;
450     unsigned short events;
451     int err;
452 
453     if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
454         return NULL;
455 
456     fd = PyObject_AsFileDescriptor(o);
457     if (fd == -1) return NULL;
458 
459     /* Modify registered fd */
460     key = PyLong_FromLong(fd);
461     if (key == NULL)
462         return NULL;
463     if (PyDict_GetItem(self->dict, key) == NULL) {
464         errno = ENOENT;
465         PyErr_SetFromErrno(PyExc_OSError);
466         Py_DECREF(key);
467         return NULL;
468     }
469     value = PyLong_FromLong(events);
470     if (value == NULL) {
471         Py_DECREF(key);
472         return NULL;
473     }
474     err = PyDict_SetItem(self->dict, key, value);
475     Py_DECREF(key);
476     Py_DECREF(value);
477     if (err < 0)
478         return NULL;
479 
480     self->ufd_uptodate = 0;
481 
482     Py_INCREF(Py_None);
483     return Py_None;
484 }
485 
486 
487 PyDoc_STRVAR(poll_unregister_doc,
488 "unregister(fd) -> None\n\n\
489 Remove a file descriptor being tracked by the polling object.");
490 
491 static PyObject *
poll_unregister(pollObject * self,PyObject * o)492 poll_unregister(pollObject *self, PyObject *o)
493 {
494     PyObject *key;
495     int fd;
496 
497     fd = PyObject_AsFileDescriptor( o );
498     if (fd == -1)
499         return NULL;
500 
501     /* Check whether the fd is already in the array */
502     key = PyLong_FromLong(fd);
503     if (key == NULL)
504         return NULL;
505 
506     if (PyDict_DelItem(self->dict, key) == -1) {
507         Py_DECREF(key);
508         /* This will simply raise the KeyError set by PyDict_DelItem
509            if the file descriptor isn't registered. */
510         return NULL;
511     }
512 
513     Py_DECREF(key);
514     self->ufd_uptodate = 0;
515 
516     Py_INCREF(Py_None);
517     return Py_None;
518 }
519 
520 PyDoc_STRVAR(poll_poll_doc,
521 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
522 Polls the set of registered file descriptors, returning a list containing \n\
523 any descriptors that have events or errors to report.");
524 
525 static PyObject *
poll_poll(pollObject * self,PyObject * args)526 poll_poll(pollObject *self, PyObject *args)
527 {
528     PyObject *result_list = NULL, *timeout_obj = NULL;
529     int poll_result, i, j;
530     PyObject *value = NULL, *num = NULL;
531     _PyTime_t timeout, ms, deadline;
532     int async_err = 0;
533 
534     if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
535         return NULL;
536     }
537 
538     /* Check values for timeout */
539     if (timeout_obj == NULL || timeout_obj == Py_None) {
540         timeout = -1;
541         ms = -1;
542         deadline = 0;   /* initialize to prevent gcc warning */
543     }
544     else {
545         if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
546                                            _PyTime_ROUND_CEILING) < 0) {
547             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
548                 PyErr_SetString(PyExc_TypeError,
549                                 "timeout must be an integer or None");
550             }
551             return NULL;
552         }
553 
554         ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
555         if (ms < INT_MIN || ms > INT_MAX) {
556             PyErr_SetString(PyExc_OverflowError, "timeout is too large");
557             return NULL;
558         }
559 
560         deadline = _PyTime_GetMonotonicClock() + timeout;
561     }
562 
563     /* Avoid concurrent poll() invocation, issue 8865 */
564     if (self->poll_running) {
565         PyErr_SetString(PyExc_RuntimeError,
566                         "concurrent poll() invocation");
567         return NULL;
568     }
569 
570     /* Ensure the ufd array is up to date */
571     if (!self->ufd_uptodate)
572         if (update_ufd_array(self) == 0)
573             return NULL;
574 
575     self->poll_running = 1;
576 
577     /* call poll() */
578     async_err = 0;
579     do {
580         Py_BEGIN_ALLOW_THREADS
581         errno = 0;
582         poll_result = poll(self->ufds, self->ufd_len, (int)ms);
583         Py_END_ALLOW_THREADS
584 
585         if (errno != EINTR)
586             break;
587 
588         /* poll() was interrupted by a signal */
589         if (PyErr_CheckSignals()) {
590             async_err = 1;
591             break;
592         }
593 
594         if (timeout >= 0) {
595             timeout = deadline - _PyTime_GetMonotonicClock();
596             if (timeout < 0) {
597                 poll_result = 0;
598                 break;
599             }
600             ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
601             /* retry poll() with the recomputed timeout */
602         }
603     } while (1);
604 
605     self->poll_running = 0;
606 
607     if (poll_result < 0) {
608         if (!async_err)
609             PyErr_SetFromErrno(PyExc_OSError);
610         return NULL;
611     }
612 
613     /* build the result list */
614 
615     result_list = PyList_New(poll_result);
616     if (!result_list)
617         return NULL;
618 
619     for (i = 0, j = 0; j < poll_result; j++) {
620         /* skip to the next fired descriptor */
621         while (!self->ufds[i].revents) {
622             i++;
623         }
624         /* if we hit a NULL return, set value to NULL
625            and break out of loop; code at end will
626            clean up result_list */
627         value = PyTuple_New(2);
628         if (value == NULL)
629             goto error;
630         num = PyLong_FromLong(self->ufds[i].fd);
631         if (num == NULL) {
632             Py_DECREF(value);
633             goto error;
634         }
635         PyTuple_SET_ITEM(value, 0, num);
636 
637         /* The &0xffff is a workaround for AIX.  'revents'
638            is a 16-bit short, and IBM assigned POLLNVAL
639            to be 0x8000, so the conversion to int results
640            in a negative number. See SF bug #923315. */
641         num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
642         if (num == NULL) {
643             Py_DECREF(value);
644             goto error;
645         }
646         PyTuple_SET_ITEM(value, 1, num);
647         if ((PyList_SetItem(result_list, j, value)) == -1) {
648             Py_DECREF(value);
649             goto error;
650         }
651         i++;
652     }
653     return result_list;
654 
655   error:
656     Py_DECREF(result_list);
657     return NULL;
658 }
659 
660 static PyMethodDef poll_methods[] = {
661     {"register",        (PyCFunction)poll_register,
662      METH_VARARGS,  poll_register_doc},
663     {"modify",          (PyCFunction)poll_modify,
664      METH_VARARGS,  poll_modify_doc},
665     {"unregister",      (PyCFunction)poll_unregister,
666      METH_O,        poll_unregister_doc},
667     {"poll",            (PyCFunction)poll_poll,
668      METH_VARARGS,  poll_poll_doc},
669     {NULL,              NULL}           /* sentinel */
670 };
671 
672 static pollObject *
newPollObject(void)673 newPollObject(void)
674 {
675     pollObject *self;
676     self = PyObject_New(pollObject, &poll_Type);
677     if (self == NULL)
678         return NULL;
679     /* ufd_uptodate is a Boolean, denoting whether the
680        array pointed to by ufds matches the contents of the dictionary. */
681     self->ufd_uptodate = 0;
682     self->ufds = NULL;
683     self->poll_running = 0;
684     self->dict = PyDict_New();
685     if (self->dict == NULL) {
686         Py_DECREF(self);
687         return NULL;
688     }
689     return self;
690 }
691 
692 static void
poll_dealloc(pollObject * self)693 poll_dealloc(pollObject *self)
694 {
695     if (self->ufds != NULL)
696         PyMem_DEL(self->ufds);
697     Py_XDECREF(self->dict);
698     PyObject_Del(self);
699 }
700 
701 static PyTypeObject poll_Type = {
702     /* The ob_type field must be initialized in the module init function
703      * to be portable to Windows without using C++. */
704     PyVarObject_HEAD_INIT(NULL, 0)
705     "select.poll",              /*tp_name*/
706     sizeof(pollObject),         /*tp_basicsize*/
707     0,                          /*tp_itemsize*/
708     /* methods */
709     (destructor)poll_dealloc, /*tp_dealloc*/
710     0,                          /*tp_print*/
711     0,                          /*tp_getattr*/
712     0,                      /*tp_setattr*/
713     0,                          /*tp_reserved*/
714     0,                          /*tp_repr*/
715     0,                          /*tp_as_number*/
716     0,                          /*tp_as_sequence*/
717     0,                          /*tp_as_mapping*/
718     0,                          /*tp_hash*/
719     0,                          /*tp_call*/
720     0,                          /*tp_str*/
721     0,                          /*tp_getattro*/
722     0,                          /*tp_setattro*/
723     0,                          /*tp_as_buffer*/
724     Py_TPFLAGS_DEFAULT,         /*tp_flags*/
725     0,                          /*tp_doc*/
726     0,                          /*tp_traverse*/
727     0,                          /*tp_clear*/
728     0,                          /*tp_richcompare*/
729     0,                          /*tp_weaklistoffset*/
730     0,                          /*tp_iter*/
731     0,                          /*tp_iternext*/
732     poll_methods,               /*tp_methods*/
733 };
734 
735 #ifdef HAVE_SYS_DEVPOLL_H
736 typedef struct {
737     PyObject_HEAD
738     int fd_devpoll;
739     int max_n_fds;
740     int n_fds;
741     struct pollfd *fds;
742 } devpollObject;
743 
744 static PyTypeObject devpoll_Type;
745 
746 static PyObject *
devpoll_err_closed(void)747 devpoll_err_closed(void)
748 {
749     PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
750     return NULL;
751 }
752 
devpoll_flush(devpollObject * self)753 static int devpoll_flush(devpollObject *self)
754 {
755     int size, n;
756 
757     if (!self->n_fds) return 0;
758 
759     size = sizeof(struct pollfd)*self->n_fds;
760     self->n_fds = 0;
761 
762     n = _Py_write(self->fd_devpoll, self->fds, size);
763     if (n == -1)
764         return -1;
765 
766     if (n < size) {
767         /*
768         ** Data writed to /dev/poll is a binary data structure. It is not
769         ** clear what to do if a partial write occurred. For now, raise
770         ** an exception and see if we actually found this problem in
771         ** the wild.
772         ** See http://bugs.python.org/issue6397.
773         */
774         PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
775                 "Please, report at http://bugs.python.org/. "
776                 "Data to report: Size tried: %d, actual size written: %d.",
777                 size, n);
778         return -1;
779     }
780     return 0;
781 }
782 
783 static PyObject *
internal_devpoll_register(devpollObject * self,PyObject * args,int remove)784 internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
785 {
786     PyObject *o;
787     int fd;
788     unsigned short events = POLLIN | POLLPRI | POLLOUT;
789 
790     if (self->fd_devpoll < 0)
791         return devpoll_err_closed();
792 
793     if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
794         return NULL;
795 
796     fd = PyObject_AsFileDescriptor(o);
797     if (fd == -1) return NULL;
798 
799     if (remove) {
800         self->fds[self->n_fds].fd = fd;
801         self->fds[self->n_fds].events = POLLREMOVE;
802 
803         if (++self->n_fds == self->max_n_fds) {
804             if (devpoll_flush(self))
805                 return NULL;
806         }
807     }
808 
809     self->fds[self->n_fds].fd = fd;
810     self->fds[self->n_fds].events = (signed short)events;
811 
812     if (++self->n_fds == self->max_n_fds) {
813         if (devpoll_flush(self))
814             return NULL;
815     }
816 
817     Py_RETURN_NONE;
818 }
819 
820 PyDoc_STRVAR(devpoll_register_doc,
821 "register(fd [, eventmask] ) -> None\n\n\
822 Register a file descriptor with the polling object.\n\
823 fd -- either an integer, or an object with a fileno() method returning an\n\
824       int.\n\
825 events -- an optional bitmask describing the type of events to check for");
826 
827 static PyObject *
devpoll_register(devpollObject * self,PyObject * args)828 devpoll_register(devpollObject *self, PyObject *args)
829 {
830     return internal_devpoll_register(self, args, 0);
831 }
832 
833 PyDoc_STRVAR(devpoll_modify_doc,
834 "modify(fd[, eventmask]) -> None\n\n\
835 Modify a possible already registered file descriptor.\n\
836 fd -- either an integer, or an object with a fileno() method returning an\n\
837       int.\n\
838 events -- an optional bitmask describing the type of events to check for");
839 
840 static PyObject *
devpoll_modify(devpollObject * self,PyObject * args)841 devpoll_modify(devpollObject *self, PyObject *args)
842 {
843     return internal_devpoll_register(self, args, 1);
844 }
845 
846 
847 PyDoc_STRVAR(devpoll_unregister_doc,
848 "unregister(fd) -> None\n\n\
849 Remove a file descriptor being tracked by the polling object.");
850 
851 static PyObject *
devpoll_unregister(devpollObject * self,PyObject * o)852 devpoll_unregister(devpollObject *self, PyObject *o)
853 {
854     int fd;
855 
856     if (self->fd_devpoll < 0)
857         return devpoll_err_closed();
858 
859     fd = PyObject_AsFileDescriptor( o );
860     if (fd == -1)
861         return NULL;
862 
863     self->fds[self->n_fds].fd = fd;
864     self->fds[self->n_fds].events = POLLREMOVE;
865 
866     if (++self->n_fds == self->max_n_fds) {
867         if (devpoll_flush(self))
868             return NULL;
869     }
870 
871     Py_RETURN_NONE;
872 }
873 
874 PyDoc_STRVAR(devpoll_poll_doc,
875 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
876 Polls the set of registered file descriptors, returning a list containing \n\
877 any descriptors that have events or errors to report.");
878 
879 static PyObject *
devpoll_poll(devpollObject * self,PyObject * args)880 devpoll_poll(devpollObject *self, PyObject *args)
881 {
882     struct dvpoll dvp;
883     PyObject *result_list = NULL, *timeout_obj = NULL;
884     int poll_result, i;
885     PyObject *value, *num1, *num2;
886     _PyTime_t timeout, ms, deadline = 0;
887 
888     if (self->fd_devpoll < 0)
889         return devpoll_err_closed();
890 
891     if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
892         return NULL;
893     }
894 
895     /* Check values for timeout */
896     if (timeout_obj == NULL || timeout_obj == Py_None) {
897         timeout = -1;
898         ms = -1;
899     }
900     else {
901         if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
902                                            _PyTime_ROUND_CEILING) < 0) {
903             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
904                 PyErr_SetString(PyExc_TypeError,
905                                 "timeout must be an integer or None");
906             }
907             return NULL;
908         }
909 
910         ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
911         if (ms < -1 || ms > INT_MAX) {
912             PyErr_SetString(PyExc_OverflowError, "timeout is too large");
913             return NULL;
914         }
915     }
916 
917     if (devpoll_flush(self))
918         return NULL;
919 
920     dvp.dp_fds = self->fds;
921     dvp.dp_nfds = self->max_n_fds;
922     dvp.dp_timeout = (int)ms;
923 
924     if (timeout >= 0)
925         deadline = _PyTime_GetMonotonicClock() + timeout;
926 
927     do {
928         /* call devpoll() */
929         Py_BEGIN_ALLOW_THREADS
930         errno = 0;
931         poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
932         Py_END_ALLOW_THREADS
933 
934         if (errno != EINTR)
935             break;
936 
937         /* devpoll() was interrupted by a signal */
938         if (PyErr_CheckSignals())
939             return NULL;
940 
941         if (timeout >= 0) {
942             timeout = deadline - _PyTime_GetMonotonicClock();
943             if (timeout < 0) {
944                 poll_result = 0;
945                 break;
946             }
947             ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
948             dvp.dp_timeout = (int)ms;
949             /* retry devpoll() with the recomputed timeout */
950         }
951     } while (1);
952 
953     if (poll_result < 0) {
954         PyErr_SetFromErrno(PyExc_IOError);
955         return NULL;
956     }
957 
958     /* build the result list */
959     result_list = PyList_New(poll_result);
960     if (!result_list)
961         return NULL;
962 
963     for (i = 0; i < poll_result; i++) {
964         num1 = PyLong_FromLong(self->fds[i].fd);
965         num2 = PyLong_FromLong(self->fds[i].revents);
966         if ((num1 == NULL) || (num2 == NULL)) {
967             Py_XDECREF(num1);
968             Py_XDECREF(num2);
969             goto error;
970         }
971         value = PyTuple_Pack(2, num1, num2);
972         Py_DECREF(num1);
973         Py_DECREF(num2);
974         if (value == NULL)
975             goto error;
976         if ((PyList_SetItem(result_list, i, value)) == -1) {
977             Py_DECREF(value);
978             goto error;
979         }
980     }
981 
982     return result_list;
983 
984   error:
985     Py_DECREF(result_list);
986     return NULL;
987 }
988 
989 static int
devpoll_internal_close(devpollObject * self)990 devpoll_internal_close(devpollObject *self)
991 {
992     int save_errno = 0;
993     if (self->fd_devpoll >= 0) {
994         int fd = self->fd_devpoll;
995         self->fd_devpoll = -1;
996         Py_BEGIN_ALLOW_THREADS
997         if (close(fd) < 0)
998             save_errno = errno;
999         Py_END_ALLOW_THREADS
1000     }
1001     return save_errno;
1002 }
1003 
1004 static PyObject*
devpoll_close(devpollObject * self)1005 devpoll_close(devpollObject *self)
1006 {
1007     errno = devpoll_internal_close(self);
1008     if (errno < 0) {
1009         PyErr_SetFromErrno(PyExc_OSError);
1010         return NULL;
1011     }
1012     Py_RETURN_NONE;
1013 }
1014 
1015 PyDoc_STRVAR(devpoll_close_doc,
1016 "close() -> None\n\
1017 \n\
1018 Close the devpoll file descriptor. Further operations on the devpoll\n\
1019 object will raise an exception.");
1020 
1021 static PyObject*
devpoll_get_closed(devpollObject * self)1022 devpoll_get_closed(devpollObject *self)
1023 {
1024     if (self->fd_devpoll < 0)
1025         Py_RETURN_TRUE;
1026     else
1027         Py_RETURN_FALSE;
1028 }
1029 
1030 static PyObject*
devpoll_fileno(devpollObject * self)1031 devpoll_fileno(devpollObject *self)
1032 {
1033     if (self->fd_devpoll < 0)
1034         return devpoll_err_closed();
1035     return PyLong_FromLong(self->fd_devpoll);
1036 }
1037 
1038 PyDoc_STRVAR(devpoll_fileno_doc,
1039 "fileno() -> int\n\
1040 \n\
1041 Return the file descriptor.");
1042 
1043 static PyMethodDef devpoll_methods[] = {
1044     {"register",        (PyCFunction)devpoll_register,
1045      METH_VARARGS,  devpoll_register_doc},
1046     {"modify",          (PyCFunction)devpoll_modify,
1047      METH_VARARGS,  devpoll_modify_doc},
1048     {"unregister",      (PyCFunction)devpoll_unregister,
1049      METH_O,        devpoll_unregister_doc},
1050     {"poll",            (PyCFunction)devpoll_poll,
1051      METH_VARARGS,  devpoll_poll_doc},
1052     {"close",           (PyCFunction)devpoll_close,    METH_NOARGS,
1053      devpoll_close_doc},
1054     {"fileno",          (PyCFunction)devpoll_fileno,    METH_NOARGS,
1055      devpoll_fileno_doc},
1056     {NULL,              NULL}           /* sentinel */
1057 };
1058 
1059 static PyGetSetDef devpoll_getsetlist[] = {
1060     {"closed", (getter)devpoll_get_closed, NULL,
1061      "True if the devpoll object is closed"},
1062     {0},
1063 };
1064 
1065 static devpollObject *
newDevPollObject(void)1066 newDevPollObject(void)
1067 {
1068     devpollObject *self;
1069     int fd_devpoll, limit_result;
1070     struct pollfd *fds;
1071     struct rlimit limit;
1072 
1073     /*
1074     ** If we try to process more that getrlimit()
1075     ** fds, the kernel will give an error, so
1076     ** we set the limit here. It is a dynamic
1077     ** value, because we can change rlimit() anytime.
1078     */
1079     limit_result = getrlimit(RLIMIT_NOFILE, &limit);
1080     if (limit_result == -1) {
1081         PyErr_SetFromErrno(PyExc_OSError);
1082         return NULL;
1083     }
1084 
1085     fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1086     if (fd_devpoll == -1)
1087         return NULL;
1088 
1089     fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1090     if (fds == NULL) {
1091         close(fd_devpoll);
1092         PyErr_NoMemory();
1093         return NULL;
1094     }
1095 
1096     self = PyObject_New(devpollObject, &devpoll_Type);
1097     if (self == NULL) {
1098         close(fd_devpoll);
1099         PyMem_DEL(fds);
1100         return NULL;
1101     }
1102     self->fd_devpoll = fd_devpoll;
1103     self->max_n_fds = limit.rlim_cur;
1104     self->n_fds = 0;
1105     self->fds = fds;
1106 
1107     return self;
1108 }
1109 
1110 static void
devpoll_dealloc(devpollObject * self)1111 devpoll_dealloc(devpollObject *self)
1112 {
1113     (void)devpoll_internal_close(self);
1114     PyMem_DEL(self->fds);
1115     PyObject_Del(self);
1116 }
1117 
1118 static PyTypeObject devpoll_Type = {
1119     /* The ob_type field must be initialized in the module init function
1120      * to be portable to Windows without using C++. */
1121     PyVarObject_HEAD_INIT(NULL, 0)
1122     "select.devpoll",           /*tp_name*/
1123     sizeof(devpollObject),      /*tp_basicsize*/
1124     0,                          /*tp_itemsize*/
1125     /* methods */
1126     (destructor)devpoll_dealloc, /*tp_dealloc*/
1127     0,                          /*tp_print*/
1128     0,                          /*tp_getattr*/
1129     0,                          /*tp_setattr*/
1130     0,                          /*tp_reserved*/
1131     0,                          /*tp_repr*/
1132     0,                          /*tp_as_number*/
1133     0,                          /*tp_as_sequence*/
1134     0,                          /*tp_as_mapping*/
1135     0,                          /*tp_hash*/
1136     0,                          /*tp_call*/
1137     0,                          /*tp_str*/
1138     0,                          /*tp_getattro*/
1139     0,                          /*tp_setattro*/
1140     0,                          /*tp_as_buffer*/
1141     Py_TPFLAGS_DEFAULT,         /*tp_flags*/
1142     0,                          /*tp_doc*/
1143     0,                          /*tp_traverse*/
1144     0,                          /*tp_clear*/
1145     0,                          /*tp_richcompare*/
1146     0,                          /*tp_weaklistoffset*/
1147     0,                          /*tp_iter*/
1148     0,                          /*tp_iternext*/
1149     devpoll_methods,            /*tp_methods*/
1150     0,                          /* tp_members */
1151     devpoll_getsetlist,         /* tp_getset */
1152 };
1153 #endif  /* HAVE_SYS_DEVPOLL_H */
1154 
1155 
1156 
1157 PyDoc_STRVAR(poll_doc,
1158 "Returns a polling object, which supports registering and\n\
1159 unregistering file descriptors, and then polling them for I/O events.");
1160 
1161 static PyObject *
select_poll(PyObject * self,PyObject * unused)1162 select_poll(PyObject *self, PyObject *unused)
1163 {
1164     return (PyObject *)newPollObject();
1165 }
1166 
1167 #ifdef HAVE_SYS_DEVPOLL_H
1168 PyDoc_STRVAR(devpoll_doc,
1169 "Returns a polling object, which supports registering and\n\
1170 unregistering file descriptors, and then polling them for I/O events.");
1171 
1172 static PyObject *
select_devpoll(PyObject * self,PyObject * unused)1173 select_devpoll(PyObject *self, PyObject *unused)
1174 {
1175     return (PyObject *)newDevPollObject();
1176 }
1177 #endif
1178 
1179 
1180 #ifdef __APPLE__
1181 /*
1182  * On some systems poll() sets errno on invalid file descriptors. We test
1183  * for this at runtime because this bug may be fixed or introduced between
1184  * OS releases.
1185  */
select_have_broken_poll(void)1186 static int select_have_broken_poll(void)
1187 {
1188     int poll_test;
1189     int filedes[2];
1190 
1191     struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
1192 
1193     /* Create a file descriptor to make invalid */
1194     if (pipe(filedes) < 0) {
1195         return 1;
1196     }
1197     poll_struct.fd = filedes[0];
1198     close(filedes[0]);
1199     close(filedes[1]);
1200     poll_test = poll(&poll_struct, 1, 0);
1201     if (poll_test < 0) {
1202         return 1;
1203     } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1204         return 1;
1205     }
1206     return 0;
1207 }
1208 #endif /* __APPLE__ */
1209 
1210 #endif /* HAVE_POLL */
1211 
1212 #ifdef HAVE_EPOLL
1213 /* **************************************************************************
1214  *                      epoll interface for Linux 2.6
1215  *
1216  * Written by Christian Heimes
1217  * Inspired by Twisted's _epoll.pyx and select.poll()
1218  */
1219 
1220 #ifdef HAVE_SYS_EPOLL_H
1221 #include <sys/epoll.h>
1222 #endif
1223 
1224 typedef struct {
1225     PyObject_HEAD
1226     SOCKET epfd;                        /* epoll control file descriptor */
1227 } pyEpoll_Object;
1228 
1229 static PyTypeObject pyEpoll_Type;
1230 #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1231 
1232 static PyObject *
pyepoll_err_closed(void)1233 pyepoll_err_closed(void)
1234 {
1235     PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
1236     return NULL;
1237 }
1238 
1239 static int
pyepoll_internal_close(pyEpoll_Object * self)1240 pyepoll_internal_close(pyEpoll_Object *self)
1241 {
1242     int save_errno = 0;
1243     if (self->epfd >= 0) {
1244         int epfd = self->epfd;
1245         self->epfd = -1;
1246         Py_BEGIN_ALLOW_THREADS
1247         if (close(epfd) < 0)
1248             save_errno = errno;
1249         Py_END_ALLOW_THREADS
1250     }
1251     return save_errno;
1252 }
1253 
1254 static PyObject *
newPyEpoll_Object(PyTypeObject * type,int sizehint,int flags,SOCKET fd)1255 newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
1256 {
1257     pyEpoll_Object *self;
1258 
1259     assert(type != NULL && type->tp_alloc != NULL);
1260     self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1261     if (self == NULL)
1262         return NULL;
1263 
1264     if (fd == -1) {
1265         Py_BEGIN_ALLOW_THREADS
1266 #ifdef HAVE_EPOLL_CREATE1
1267         flags |= EPOLL_CLOEXEC;
1268         if (flags)
1269             self->epfd = epoll_create1(flags);
1270         else
1271 #endif
1272         self->epfd = epoll_create(sizehint);
1273         Py_END_ALLOW_THREADS
1274     }
1275     else {
1276         self->epfd = fd;
1277     }
1278     if (self->epfd < 0) {
1279         Py_DECREF(self);
1280         PyErr_SetFromErrno(PyExc_OSError);
1281         return NULL;
1282     }
1283 
1284 #ifndef HAVE_EPOLL_CREATE1
1285     if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
1286         Py_DECREF(self);
1287         return NULL;
1288     }
1289 #endif
1290 
1291     return (PyObject *)self;
1292 }
1293 
1294 
1295 static PyObject *
pyepoll_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1296 pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1297 {
1298     int flags = 0, sizehint = FD_SETSIZE - 1;
1299     static char *kwlist[] = {"sizehint", "flags", NULL};
1300 
1301     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1302                                      &sizehint, &flags))
1303         return NULL;
1304     if (sizehint < 0) {
1305         PyErr_SetString(PyExc_ValueError, "negative sizehint");
1306         return NULL;
1307     }
1308 
1309     return newPyEpoll_Object(type, sizehint, flags, -1);
1310 }
1311 
1312 
1313 static void
pyepoll_dealloc(pyEpoll_Object * self)1314 pyepoll_dealloc(pyEpoll_Object *self)
1315 {
1316     (void)pyepoll_internal_close(self);
1317     Py_TYPE(self)->tp_free(self);
1318 }
1319 
1320 static PyObject*
pyepoll_close(pyEpoll_Object * self)1321 pyepoll_close(pyEpoll_Object *self)
1322 {
1323     errno = pyepoll_internal_close(self);
1324     if (errno < 0) {
1325         PyErr_SetFromErrno(PyExc_OSError);
1326         return NULL;
1327     }
1328     Py_RETURN_NONE;
1329 }
1330 
1331 PyDoc_STRVAR(pyepoll_close_doc,
1332 "close() -> None\n\
1333 \n\
1334 Close the epoll control file descriptor. Further operations on the epoll\n\
1335 object will raise an exception.");
1336 
1337 static PyObject*
pyepoll_get_closed(pyEpoll_Object * self)1338 pyepoll_get_closed(pyEpoll_Object *self)
1339 {
1340     if (self->epfd < 0)
1341         Py_RETURN_TRUE;
1342     else
1343         Py_RETURN_FALSE;
1344 }
1345 
1346 static PyObject*
pyepoll_fileno(pyEpoll_Object * self)1347 pyepoll_fileno(pyEpoll_Object *self)
1348 {
1349     if (self->epfd < 0)
1350         return pyepoll_err_closed();
1351     return PyLong_FromLong(self->epfd);
1352 }
1353 
1354 PyDoc_STRVAR(pyepoll_fileno_doc,
1355 "fileno() -> int\n\
1356 \n\
1357 Return the epoll control file descriptor.");
1358 
1359 static PyObject*
pyepoll_fromfd(PyObject * cls,PyObject * args)1360 pyepoll_fromfd(PyObject *cls, PyObject *args)
1361 {
1362     SOCKET fd;
1363 
1364     if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1365         return NULL;
1366 
1367     return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
1368 }
1369 
1370 PyDoc_STRVAR(pyepoll_fromfd_doc,
1371 "fromfd(fd) -> epoll\n\
1372 \n\
1373 Create an epoll object from a given control fd.");
1374 
1375 static PyObject *
pyepoll_internal_ctl(int epfd,int op,PyObject * pfd,unsigned int events)1376 pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1377 {
1378     struct epoll_event ev;
1379     int result;
1380     int fd;
1381 
1382     if (epfd < 0)
1383         return pyepoll_err_closed();
1384 
1385     fd = PyObject_AsFileDescriptor(pfd);
1386     if (fd == -1) {
1387         return NULL;
1388     }
1389 
1390     switch (op) {
1391     case EPOLL_CTL_ADD:
1392     case EPOLL_CTL_MOD:
1393         ev.events = events;
1394         ev.data.fd = fd;
1395         Py_BEGIN_ALLOW_THREADS
1396         result = epoll_ctl(epfd, op, fd, &ev);
1397         Py_END_ALLOW_THREADS
1398         break;
1399     case EPOLL_CTL_DEL:
1400         /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1401          * operation required a non-NULL pointer in event, even
1402          * though this argument is ignored. */
1403         Py_BEGIN_ALLOW_THREADS
1404         result = epoll_ctl(epfd, op, fd, &ev);
1405         if (errno == EBADF) {
1406             /* fd already closed */
1407             result = 0;
1408             errno = 0;
1409         }
1410         Py_END_ALLOW_THREADS
1411         break;
1412     default:
1413         result = -1;
1414         errno = EINVAL;
1415     }
1416 
1417     if (result < 0) {
1418         PyErr_SetFromErrno(PyExc_OSError);
1419         return NULL;
1420     }
1421     Py_RETURN_NONE;
1422 }
1423 
1424 static PyObject *
pyepoll_register(pyEpoll_Object * self,PyObject * args,PyObject * kwds)1425 pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1426 {
1427     PyObject *pfd;
1428     unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1429     static char *kwlist[] = {"fd", "eventmask", NULL};
1430 
1431     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1432                                      &pfd, &events)) {
1433         return NULL;
1434     }
1435 
1436     return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
1437 }
1438 
1439 PyDoc_STRVAR(pyepoll_register_doc,
1440 "register(fd[, eventmask]) -> None\n\
1441 \n\
1442 Registers a new fd or raises an OSError if the fd is already registered.\n\
1443 fd is the target file descriptor of the operation.\n\
1444 events is a bit set composed of the various EPOLL constants; the default\n\
1445 is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
1446 \n\
1447 The epoll interface supports all file descriptors that support poll.");
1448 
1449 static PyObject *
pyepoll_modify(pyEpoll_Object * self,PyObject * args,PyObject * kwds)1450 pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1451 {
1452     PyObject *pfd;
1453     unsigned int events;
1454     static char *kwlist[] = {"fd", "eventmask", NULL};
1455 
1456     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1457                                      &pfd, &events)) {
1458         return NULL;
1459     }
1460 
1461     return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
1462 }
1463 
1464 PyDoc_STRVAR(pyepoll_modify_doc,
1465 "modify(fd, eventmask) -> None\n\
1466 \n\
1467 fd is the target file descriptor of the operation\n\
1468 events is a bit set composed of the various EPOLL constants");
1469 
1470 static PyObject *
pyepoll_unregister(pyEpoll_Object * self,PyObject * args,PyObject * kwds)1471 pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1472 {
1473     PyObject *pfd;
1474     static char *kwlist[] = {"fd", NULL};
1475 
1476     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1477                                      &pfd)) {
1478         return NULL;
1479     }
1480 
1481     return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
1482 }
1483 
1484 PyDoc_STRVAR(pyepoll_unregister_doc,
1485 "unregister(fd) -> None\n\
1486 \n\
1487 fd is the target file descriptor of the operation.");
1488 
1489 static PyObject *
pyepoll_poll(pyEpoll_Object * self,PyObject * args,PyObject * kwds)1490 pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1491 {
1492     static char *kwlist[] = {"timeout", "maxevents", NULL};
1493     PyObject *timeout_obj = NULL;
1494     int maxevents = -1;
1495     int nfds, i;
1496     PyObject *elist = NULL, *etuple = NULL;
1497     struct epoll_event *evs = NULL;
1498     _PyTime_t timeout, ms, deadline;
1499 
1500     if (self->epfd < 0)
1501         return pyepoll_err_closed();
1502 
1503     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1504                                      &timeout_obj, &maxevents)) {
1505         return NULL;
1506     }
1507 
1508     if (timeout_obj == NULL || timeout_obj == Py_None) {
1509         timeout = -1;
1510         ms = -1;
1511         deadline = 0;   /* initialize to prevent gcc warning */
1512     }
1513     else {
1514         /* epoll_wait() has a resolution of 1 millisecond, round towards
1515            infinity to wait at least timeout seconds. */
1516         if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
1517                                       _PyTime_ROUND_CEILING) < 0) {
1518             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1519                 PyErr_SetString(PyExc_TypeError,
1520                                 "timeout must be an integer or None");
1521             }
1522             return NULL;
1523         }
1524 
1525         ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1526         if (ms < INT_MIN || ms > INT_MAX) {
1527             PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1528             return NULL;
1529         }
1530 
1531         deadline = _PyTime_GetMonotonicClock() + timeout;
1532     }
1533 
1534     if (maxevents == -1) {
1535         maxevents = FD_SETSIZE-1;
1536     }
1537     else if (maxevents < 1) {
1538         PyErr_Format(PyExc_ValueError,
1539                      "maxevents must be greater than 0, got %d",
1540                      maxevents);
1541         return NULL;
1542     }
1543 
1544     evs = PyMem_New(struct epoll_event, maxevents);
1545     if (evs == NULL) {
1546         PyErr_NoMemory();
1547         return NULL;
1548     }
1549 
1550     do {
1551         Py_BEGIN_ALLOW_THREADS
1552         errno = 0;
1553         nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1554         Py_END_ALLOW_THREADS
1555 
1556         if (errno != EINTR)
1557             break;
1558 
1559         /* poll() was interrupted by a signal */
1560         if (PyErr_CheckSignals())
1561             goto error;
1562 
1563         if (timeout >= 0) {
1564             timeout = deadline - _PyTime_GetMonotonicClock();
1565             if (timeout < 0) {
1566                 nfds = 0;
1567                 break;
1568             }
1569             ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1570             /* retry epoll_wait() with the recomputed timeout */
1571         }
1572     } while(1);
1573 
1574     if (nfds < 0) {
1575         PyErr_SetFromErrno(PyExc_OSError);
1576         goto error;
1577     }
1578 
1579     elist = PyList_New(nfds);
1580     if (elist == NULL) {
1581         goto error;
1582     }
1583 
1584     for (i = 0; i < nfds; i++) {
1585         etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1586         if (etuple == NULL) {
1587             Py_CLEAR(elist);
1588             goto error;
1589         }
1590         PyList_SET_ITEM(elist, i, etuple);
1591     }
1592 
1593     error:
1594     PyMem_Free(evs);
1595     return elist;
1596 }
1597 
1598 PyDoc_STRVAR(pyepoll_poll_doc,
1599 "poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1600 \n\
1601 Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1602 in seconds (as float). -1 makes poll wait indefinitely.\n\
1603 Up to maxevents are returned to the caller.");
1604 
1605 static PyObject *
pyepoll_enter(pyEpoll_Object * self,PyObject * args)1606 pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1607 {
1608     if (self->epfd < 0)
1609         return pyepoll_err_closed();
1610 
1611     Py_INCREF(self);
1612     return (PyObject *)self;
1613 }
1614 
1615 static PyObject *
pyepoll_exit(PyObject * self,PyObject * args)1616 pyepoll_exit(PyObject *self, PyObject *args)
1617 {
1618     _Py_IDENTIFIER(close);
1619 
1620     return _PyObject_CallMethodId(self, &PyId_close, NULL);
1621 }
1622 
1623 static PyMethodDef pyepoll_methods[] = {
1624     {"fromfd",          (PyCFunction)pyepoll_fromfd,
1625      METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1626     {"close",           (PyCFunction)pyepoll_close,     METH_NOARGS,
1627      pyepoll_close_doc},
1628     {"fileno",          (PyCFunction)pyepoll_fileno,    METH_NOARGS,
1629      pyepoll_fileno_doc},
1630     {"modify",          (PyCFunction)pyepoll_modify,
1631      METH_VARARGS | METH_KEYWORDS,      pyepoll_modify_doc},
1632     {"register",        (PyCFunction)pyepoll_register,
1633      METH_VARARGS | METH_KEYWORDS,      pyepoll_register_doc},
1634     {"unregister",      (PyCFunction)pyepoll_unregister,
1635      METH_VARARGS | METH_KEYWORDS,      pyepoll_unregister_doc},
1636     {"poll",            (PyCFunction)pyepoll_poll,
1637      METH_VARARGS | METH_KEYWORDS,      pyepoll_poll_doc},
1638     {"__enter__",           (PyCFunction)pyepoll_enter,     METH_NOARGS,
1639      NULL},
1640     {"__exit__",           (PyCFunction)pyepoll_exit,     METH_VARARGS,
1641      NULL},
1642     {NULL,      NULL},
1643 };
1644 
1645 static PyGetSetDef pyepoll_getsetlist[] = {
1646     {"closed", (getter)pyepoll_get_closed, NULL,
1647      "True if the epoll handler is closed"},
1648     {0},
1649 };
1650 
1651 PyDoc_STRVAR(pyepoll_doc,
1652 "select.epoll(sizehint=-1, flags=0)\n\
1653 \n\
1654 Returns an epolling object\n\
1655 \n\
1656 sizehint must be a positive integer or -1 for the default size. The\n\
1657 sizehint is used to optimize internal data structures. It doesn't limit\n\
1658 the maximum number of monitored events.");
1659 
1660 static PyTypeObject pyEpoll_Type = {
1661     PyVarObject_HEAD_INIT(NULL, 0)
1662     "select.epoll",                                     /* tp_name */
1663     sizeof(pyEpoll_Object),                             /* tp_basicsize */
1664     0,                                                  /* tp_itemsize */
1665     (destructor)pyepoll_dealloc,                        /* tp_dealloc */
1666     0,                                                  /* tp_print */
1667     0,                                                  /* tp_getattr */
1668     0,                                                  /* tp_setattr */
1669     0,                                                  /* tp_reserved */
1670     0,                                                  /* tp_repr */
1671     0,                                                  /* tp_as_number */
1672     0,                                                  /* tp_as_sequence */
1673     0,                                                  /* tp_as_mapping */
1674     0,                                                  /* tp_hash */
1675     0,                                                  /* tp_call */
1676     0,                                                  /* tp_str */
1677     PyObject_GenericGetAttr,                            /* tp_getattro */
1678     0,                                                  /* tp_setattro */
1679     0,                                                  /* tp_as_buffer */
1680     Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
1681     pyepoll_doc,                                        /* tp_doc */
1682     0,                                                  /* tp_traverse */
1683     0,                                                  /* tp_clear */
1684     0,                                                  /* tp_richcompare */
1685     0,                                                  /* tp_weaklistoffset */
1686     0,                                                  /* tp_iter */
1687     0,                                                  /* tp_iternext */
1688     pyepoll_methods,                                    /* tp_methods */
1689     0,                                                  /* tp_members */
1690     pyepoll_getsetlist,                                 /* tp_getset */
1691     0,                                                  /* tp_base */
1692     0,                                                  /* tp_dict */
1693     0,                                                  /* tp_descr_get */
1694     0,                                                  /* tp_descr_set */
1695     0,                                                  /* tp_dictoffset */
1696     0,                                                  /* tp_init */
1697     0,                                                  /* tp_alloc */
1698     pyepoll_new,                                        /* tp_new */
1699     0,                                                  /* tp_free */
1700 };
1701 
1702 #endif /* HAVE_EPOLL */
1703 
1704 #ifdef HAVE_KQUEUE
1705 /* **************************************************************************
1706  *                      kqueue interface for BSD
1707  *
1708  * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1709  * All rights reserved.
1710  *
1711  * Redistribution and use in source and binary forms, with or without
1712  * modification, are permitted provided that the following conditions
1713  * are met:
1714  * 1. Redistributions of source code must retain the above copyright
1715  *    notice, this list of conditions and the following disclaimer.
1716  * 2. Redistributions in binary form must reproduce the above copyright
1717  *    notice, this list of conditions and the following disclaimer in the
1718  *    documentation and/or other materials provided with the distribution.
1719  *
1720  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1721  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1722  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1723  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1724  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1725  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1726  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1727  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1728  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1729  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1730  * SUCH DAMAGE.
1731  */
1732 
1733 #ifdef HAVE_SYS_EVENT_H
1734 #include <sys/event.h>
1735 #endif
1736 
1737 PyDoc_STRVAR(kqueue_event_doc,
1738 "kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
1739 \n\
1740 This object is the equivalent of the struct kevent for the C API.\n\
1741 \n\
1742 See the kqueue manpage for more detailed information about the meaning\n\
1743 of the arguments.\n\
1744 \n\
1745 One minor note: while you might hope that udata could store a\n\
1746 reference to a python object, it cannot, because it is impossible to\n\
1747 keep a proper reference count of the object once it's passed into the\n\
1748 kernel. Therefore, I have restricted it to only storing an integer.  I\n\
1749 recommend ignoring it and simply using the 'ident' field to key off\n\
1750 of. You could also set up a dictionary on the python side to store a\n\
1751 udata->object mapping.");
1752 
1753 typedef struct {
1754     PyObject_HEAD
1755     struct kevent e;
1756 } kqueue_event_Object;
1757 
1758 static PyTypeObject kqueue_event_Type;
1759 
1760 #define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1761 
1762 typedef struct {
1763     PyObject_HEAD
1764     SOCKET kqfd;                /* kqueue control fd */
1765 } kqueue_queue_Object;
1766 
1767 static PyTypeObject kqueue_queue_Type;
1768 
1769 #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1770 
1771 #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1772 #   error uintptr_t does not match void *!
1773 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1774 #   define T_UINTPTRT         T_ULONGLONG
1775 #   define T_INTPTRT          T_LONGLONG
1776 #   define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1777 #   define UINTPTRT_FMT_UNIT  "K"
1778 #   define INTPTRT_FMT_UNIT   "L"
1779 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1780 #   define T_UINTPTRT         T_ULONG
1781 #   define T_INTPTRT          T_LONG
1782 #   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1783 #   define UINTPTRT_FMT_UNIT  "k"
1784 #   define INTPTRT_FMT_UNIT   "l"
1785 #elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1786 #   define T_UINTPTRT         T_UINT
1787 #   define T_INTPTRT          T_INT
1788 #   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1789 #   define UINTPTRT_FMT_UNIT  "I"
1790 #   define INTPTRT_FMT_UNIT   "i"
1791 #else
1792 #   error uintptr_t does not match int, long, or long long!
1793 #endif
1794 
1795 /*
1796  * kevent is not standard and its members vary across BSDs.
1797  */
1798 #if !defined(__OpenBSD__)
1799 #   define IDENT_TYPE  T_UINTPTRT
1800 #   define IDENT_CAST  intptr_t
1801 #   define DATA_TYPE   T_INTPTRT
1802 #   define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1803 #   define IDENT_AsType PyLong_AsUintptr_t
1804 #else
1805 #   define IDENT_TYPE  T_UINT
1806 #   define IDENT_CAST  int
1807 #   define DATA_TYPE   T_INT
1808 #   define DATA_FMT_UNIT "i"
1809 #   define IDENT_AsType PyLong_AsUnsignedLong
1810 #endif
1811 
1812 /* Unfortunately, we can't store python objects in udata, because
1813  * kevents in the kernel can be removed without warning, which would
1814  * forever lose the refcount on the object stored with it.
1815  */
1816 
1817 #define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1818 static struct PyMemberDef kqueue_event_members[] = {
1819     {"ident",           IDENT_TYPE,     KQ_OFF(e.ident)},
1820     {"filter",          T_SHORT,        KQ_OFF(e.filter)},
1821     {"flags",           T_USHORT,       KQ_OFF(e.flags)},
1822     {"fflags",          T_UINT,         KQ_OFF(e.fflags)},
1823     {"data",            DATA_TYPE,      KQ_OFF(e.data)},
1824     {"udata",           T_UINTPTRT,     KQ_OFF(e.udata)},
1825     {NULL} /* Sentinel */
1826 };
1827 #undef KQ_OFF
1828 
1829 static PyObject *
1830 
kqueue_event_repr(kqueue_event_Object * s)1831 kqueue_event_repr(kqueue_event_Object *s)
1832 {
1833     char buf[1024];
1834     PyOS_snprintf(
1835         buf, sizeof(buf),
1836         "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1837         "data=0x%zd udata=%p>",
1838         (size_t)(s->e.ident), s->e.filter, s->e.flags,
1839         s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1840     return PyUnicode_FromString(buf);
1841 }
1842 
1843 static int
kqueue_event_init(kqueue_event_Object * self,PyObject * args,PyObject * kwds)1844 kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1845 {
1846     PyObject *pfd;
1847     static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1848                              "data", "udata", NULL};
1849     static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
1850 
1851     EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1852 
1853     if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1854         &pfd, &(self->e.filter), &(self->e.flags),
1855         &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1856         return -1;
1857     }
1858 
1859     if (PyLong_Check(pfd)
1860 #if IDENT_TYPE == T_UINT
1861         && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
1862 #endif
1863     ) {
1864         self->e.ident = IDENT_AsType(pfd);
1865     }
1866     else {
1867         self->e.ident = PyObject_AsFileDescriptor(pfd);
1868     }
1869     if (PyErr_Occurred()) {
1870         return -1;
1871     }
1872     return 0;
1873 }
1874 
1875 static PyObject *
kqueue_event_richcompare(kqueue_event_Object * s,kqueue_event_Object * o,int op)1876 kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1877                          int op)
1878 {
1879     intptr_t result = 0;
1880 
1881     if (!kqueue_event_Check(o)) {
1882         if (op == Py_EQ || op == Py_NE) {
1883             PyObject *res = op == Py_EQ ? Py_False : Py_True;
1884             Py_INCREF(res);
1885             return res;
1886         }
1887         PyErr_Format(PyExc_TypeError,
1888             "can't compare %.200s to %.200s",
1889             Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1890         return NULL;
1891     }
1892     if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
1893         ((result = s->e.filter - o->e.filter) == 0) &&
1894         ((result = s->e.flags - o->e.flags) == 0) &&
1895         ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
1896         ((result = s->e.data - o->e.data) == 0) &&
1897         ((result = s->e.udata - o->e.udata) == 0)
1898        ) {
1899         result = 0;
1900     }
1901 
1902     switch (op) {
1903     case Py_EQ:
1904         result = (result == 0);
1905         break;
1906     case Py_NE:
1907         result = (result != 0);
1908         break;
1909     case Py_LE:
1910         result = (result <= 0);
1911         break;
1912     case Py_GE:
1913         result = (result >= 0);
1914         break;
1915     case Py_LT:
1916         result = (result < 0);
1917         break;
1918     case Py_GT:
1919         result = (result > 0);
1920         break;
1921     }
1922     return PyBool_FromLong((long)result);
1923 }
1924 
1925 static PyTypeObject kqueue_event_Type = {
1926     PyVarObject_HEAD_INIT(NULL, 0)
1927     "select.kevent",                                    /* tp_name */
1928     sizeof(kqueue_event_Object),                        /* tp_basicsize */
1929     0,                                                  /* tp_itemsize */
1930     0,                                                  /* tp_dealloc */
1931     0,                                                  /* tp_print */
1932     0,                                                  /* tp_getattr */
1933     0,                                                  /* tp_setattr */
1934     0,                                                  /* tp_reserved */
1935     (reprfunc)kqueue_event_repr,                        /* tp_repr */
1936     0,                                                  /* tp_as_number */
1937     0,                                                  /* tp_as_sequence */
1938     0,                                                  /* tp_as_mapping */
1939     0,                                                  /* tp_hash */
1940     0,                                                  /* tp_call */
1941     0,                                                  /* tp_str */
1942     0,                                                  /* tp_getattro */
1943     0,                                                  /* tp_setattro */
1944     0,                                                  /* tp_as_buffer */
1945     Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
1946     kqueue_event_doc,                                   /* tp_doc */
1947     0,                                                  /* tp_traverse */
1948     0,                                                  /* tp_clear */
1949     (richcmpfunc)kqueue_event_richcompare,              /* tp_richcompare */
1950     0,                                                  /* tp_weaklistoffset */
1951     0,                                                  /* tp_iter */
1952     0,                                                  /* tp_iternext */
1953     0,                                                  /* tp_methods */
1954     kqueue_event_members,                               /* tp_members */
1955     0,                                                  /* tp_getset */
1956     0,                                                  /* tp_base */
1957     0,                                                  /* tp_dict */
1958     0,                                                  /* tp_descr_get */
1959     0,                                                  /* tp_descr_set */
1960     0,                                                  /* tp_dictoffset */
1961     (initproc)kqueue_event_init,                        /* tp_init */
1962     0,                                                  /* tp_alloc */
1963     0,                                                  /* tp_new */
1964     0,                                                  /* tp_free */
1965 };
1966 
1967 static PyObject *
kqueue_queue_err_closed(void)1968 kqueue_queue_err_closed(void)
1969 {
1970     PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
1971     return NULL;
1972 }
1973 
1974 static int
kqueue_queue_internal_close(kqueue_queue_Object * self)1975 kqueue_queue_internal_close(kqueue_queue_Object *self)
1976 {
1977     int save_errno = 0;
1978     if (self->kqfd >= 0) {
1979         int kqfd = self->kqfd;
1980         self->kqfd = -1;
1981         Py_BEGIN_ALLOW_THREADS
1982         if (close(kqfd) < 0)
1983             save_errno = errno;
1984         Py_END_ALLOW_THREADS
1985     }
1986     return save_errno;
1987 }
1988 
1989 static PyObject *
newKqueue_Object(PyTypeObject * type,SOCKET fd)1990 newKqueue_Object(PyTypeObject *type, SOCKET fd)
1991 {
1992     kqueue_queue_Object *self;
1993     assert(type != NULL && type->tp_alloc != NULL);
1994     self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1995     if (self == NULL) {
1996         return NULL;
1997     }
1998 
1999     if (fd == -1) {
2000         Py_BEGIN_ALLOW_THREADS
2001         self->kqfd = kqueue();
2002         Py_END_ALLOW_THREADS
2003     }
2004     else {
2005         self->kqfd = fd;
2006     }
2007     if (self->kqfd < 0) {
2008         Py_DECREF(self);
2009         PyErr_SetFromErrno(PyExc_OSError);
2010         return NULL;
2011     }
2012 
2013     if (fd == -1) {
2014         if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2015             Py_DECREF(self);
2016             return NULL;
2017         }
2018     }
2019     return (PyObject *)self;
2020 }
2021 
2022 static PyObject *
kqueue_queue_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2023 kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2024 {
2025     if ((args != NULL && PyObject_Size(args)) ||
2026                     (kwds != NULL && PyObject_Size(kwds))) {
2027         PyErr_SetString(PyExc_ValueError,
2028                         "select.kqueue doesn't accept arguments");
2029         return NULL;
2030     }
2031 
2032     return newKqueue_Object(type, -1);
2033 }
2034 
2035 static void
kqueue_queue_dealloc(kqueue_queue_Object * self)2036 kqueue_queue_dealloc(kqueue_queue_Object *self)
2037 {
2038     kqueue_queue_internal_close(self);
2039     Py_TYPE(self)->tp_free(self);
2040 }
2041 
2042 static PyObject*
kqueue_queue_close(kqueue_queue_Object * self)2043 kqueue_queue_close(kqueue_queue_Object *self)
2044 {
2045     errno = kqueue_queue_internal_close(self);
2046     if (errno < 0) {
2047         PyErr_SetFromErrno(PyExc_OSError);
2048         return NULL;
2049     }
2050     Py_RETURN_NONE;
2051 }
2052 
2053 PyDoc_STRVAR(kqueue_queue_close_doc,
2054 "close() -> None\n\
2055 \n\
2056 Close the kqueue control file descriptor. Further operations on the kqueue\n\
2057 object will raise an exception.");
2058 
2059 static PyObject*
kqueue_queue_get_closed(kqueue_queue_Object * self)2060 kqueue_queue_get_closed(kqueue_queue_Object *self)
2061 {
2062     if (self->kqfd < 0)
2063         Py_RETURN_TRUE;
2064     else
2065         Py_RETURN_FALSE;
2066 }
2067 
2068 static PyObject*
kqueue_queue_fileno(kqueue_queue_Object * self)2069 kqueue_queue_fileno(kqueue_queue_Object *self)
2070 {
2071     if (self->kqfd < 0)
2072         return kqueue_queue_err_closed();
2073     return PyLong_FromLong(self->kqfd);
2074 }
2075 
2076 PyDoc_STRVAR(kqueue_queue_fileno_doc,
2077 "fileno() -> int\n\
2078 \n\
2079 Return the kqueue control file descriptor.");
2080 
2081 static PyObject*
kqueue_queue_fromfd(PyObject * cls,PyObject * args)2082 kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2083 {
2084     SOCKET fd;
2085 
2086     if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2087         return NULL;
2088 
2089     return newKqueue_Object((PyTypeObject*)cls, fd);
2090 }
2091 
2092 PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2093 "fromfd(fd) -> kqueue\n\
2094 \n\
2095 Create a kqueue object from a given control fd.");
2096 
2097 static PyObject *
kqueue_queue_control(kqueue_queue_Object * self,PyObject * args)2098 kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2099 {
2100     int nevents = 0;
2101     int gotevents = 0;
2102     int nchanges = 0;
2103     int i = 0;
2104     PyObject *otimeout = NULL;
2105     PyObject *ch = NULL;
2106     PyObject *it = NULL, *ei = NULL;
2107     PyObject *result = NULL;
2108     struct kevent *evl = NULL;
2109     struct kevent *chl = NULL;
2110     struct timespec timeoutspec;
2111     struct timespec *ptimeoutspec;
2112     _PyTime_t timeout, deadline = 0;
2113 
2114     if (self->kqfd < 0)
2115         return kqueue_queue_err_closed();
2116 
2117     if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2118         return NULL;
2119 
2120     if (nevents < 0) {
2121         PyErr_Format(PyExc_ValueError,
2122             "Length of eventlist must be 0 or positive, got %d",
2123             nevents);
2124         return NULL;
2125     }
2126 
2127     if (otimeout == Py_None || otimeout == NULL) {
2128         ptimeoutspec = NULL;
2129     }
2130     else {
2131         if (_PyTime_FromSecondsObject(&timeout,
2132                                       otimeout, _PyTime_ROUND_CEILING) < 0) {
2133             PyErr_Format(PyExc_TypeError,
2134                 "timeout argument must be a number "
2135                 "or None, got %.200s",
2136                 Py_TYPE(otimeout)->tp_name);
2137             return NULL;
2138         }
2139 
2140         if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2141             return NULL;
2142 
2143         if (timeoutspec.tv_sec < 0) {
2144             PyErr_SetString(PyExc_ValueError,
2145                             "timeout must be positive or None");
2146             return NULL;
2147         }
2148         ptimeoutspec = &timeoutspec;
2149     }
2150 
2151     if (ch != NULL && ch != Py_None) {
2152         it = PyObject_GetIter(ch);
2153         if (it == NULL) {
2154             PyErr_SetString(PyExc_TypeError,
2155                             "changelist is not iterable");
2156             return NULL;
2157         }
2158         nchanges = PyObject_Size(ch);
2159         if (nchanges < 0) {
2160             goto error;
2161         }
2162 
2163         chl = PyMem_New(struct kevent, nchanges);
2164         if (chl == NULL) {
2165             PyErr_NoMemory();
2166             goto error;
2167         }
2168         i = 0;
2169         while ((ei = PyIter_Next(it)) != NULL) {
2170             if (!kqueue_event_Check(ei)) {
2171                 Py_DECREF(ei);
2172                 PyErr_SetString(PyExc_TypeError,
2173                     "changelist must be an iterable of "
2174                     "select.kevent objects");
2175                 goto error;
2176             } else {
2177                 chl[i++] = ((kqueue_event_Object *)ei)->e;
2178             }
2179             Py_DECREF(ei);
2180         }
2181     }
2182     Py_CLEAR(it);
2183 
2184     /* event list */
2185     if (nevents) {
2186         evl = PyMem_New(struct kevent, nevents);
2187         if (evl == NULL) {
2188             PyErr_NoMemory();
2189             goto error;
2190         }
2191     }
2192 
2193     if (ptimeoutspec)
2194         deadline = _PyTime_GetMonotonicClock() + timeout;
2195 
2196     do {
2197         Py_BEGIN_ALLOW_THREADS
2198         errno = 0;
2199         gotevents = kevent(self->kqfd, chl, nchanges,
2200                            evl, nevents, ptimeoutspec);
2201         Py_END_ALLOW_THREADS
2202 
2203         if (errno != EINTR)
2204             break;
2205 
2206         /* kevent() was interrupted by a signal */
2207         if (PyErr_CheckSignals())
2208             goto error;
2209 
2210         if (ptimeoutspec) {
2211             timeout = deadline - _PyTime_GetMonotonicClock();
2212             if (timeout < 0) {
2213                 gotevents = 0;
2214                 break;
2215             }
2216             if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2217                 goto error;
2218             /* retry kevent() with the recomputed timeout */
2219         }
2220     } while (1);
2221 
2222     if (gotevents == -1) {
2223         PyErr_SetFromErrno(PyExc_OSError);
2224         goto error;
2225     }
2226 
2227     result = PyList_New(gotevents);
2228     if (result == NULL) {
2229         goto error;
2230     }
2231 
2232     for (i = 0; i < gotevents; i++) {
2233         kqueue_event_Object *ch;
2234 
2235         ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2236         if (ch == NULL) {
2237             goto error;
2238         }
2239         ch->e = evl[i];
2240         PyList_SET_ITEM(result, i, (PyObject *)ch);
2241     }
2242     PyMem_Free(chl);
2243     PyMem_Free(evl);
2244     return result;
2245 
2246     error:
2247     PyMem_Free(chl);
2248     PyMem_Free(evl);
2249     Py_XDECREF(result);
2250     Py_XDECREF(it);
2251     return NULL;
2252 }
2253 
2254 PyDoc_STRVAR(kqueue_queue_control_doc,
2255 "control(changelist, max_events[, timeout=None]) -> eventlist\n\
2256 \n\
2257 Calls the kernel kevent function.\n\
2258 - changelist must be a list of kevent objects describing the changes\n\
2259   to be made to the kernel's watch list or None.\n\
2260 - max_events lets you specify the maximum number of events that the\n\
2261   kernel will return.\n\
2262 - timeout is the maximum time to wait in seconds, or else None,\n\
2263   to wait forever. timeout accepts floats for smaller timeouts, too.");
2264 
2265 
2266 static PyMethodDef kqueue_queue_methods[] = {
2267     {"fromfd",          (PyCFunction)kqueue_queue_fromfd,
2268      METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2269     {"close",           (PyCFunction)kqueue_queue_close,        METH_NOARGS,
2270      kqueue_queue_close_doc},
2271     {"fileno",          (PyCFunction)kqueue_queue_fileno,       METH_NOARGS,
2272      kqueue_queue_fileno_doc},
2273     {"control",         (PyCFunction)kqueue_queue_control,
2274      METH_VARARGS ,     kqueue_queue_control_doc},
2275     {NULL,      NULL},
2276 };
2277 
2278 static PyGetSetDef kqueue_queue_getsetlist[] = {
2279     {"closed", (getter)kqueue_queue_get_closed, NULL,
2280      "True if the kqueue handler is closed"},
2281     {0},
2282 };
2283 
2284 PyDoc_STRVAR(kqueue_queue_doc,
2285 "Kqueue syscall wrapper.\n\
2286 \n\
2287 For example, to start watching a socket for input:\n\
2288 >>> kq = kqueue()\n\
2289 >>> sock = socket()\n\
2290 >>> sock.connect((host, port))\n\
2291 >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2292 \n\
2293 To wait one second for it to become writeable:\n\
2294 >>> kq.control(None, 1, 1000)\n\
2295 \n\
2296 To stop listening:\n\
2297 >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2298 
2299 static PyTypeObject kqueue_queue_Type = {
2300     PyVarObject_HEAD_INIT(NULL, 0)
2301     "select.kqueue",                                    /* tp_name */
2302     sizeof(kqueue_queue_Object),                        /* tp_basicsize */
2303     0,                                                  /* tp_itemsize */
2304     (destructor)kqueue_queue_dealloc,                   /* tp_dealloc */
2305     0,                                                  /* tp_print */
2306     0,                                                  /* tp_getattr */
2307     0,                                                  /* tp_setattr */
2308     0,                                                  /* tp_reserved */
2309     0,                                                  /* tp_repr */
2310     0,                                                  /* tp_as_number */
2311     0,                                                  /* tp_as_sequence */
2312     0,                                                  /* tp_as_mapping */
2313     0,                                                  /* tp_hash */
2314     0,                                                  /* tp_call */
2315     0,                                                  /* tp_str */
2316     0,                                                  /* tp_getattro */
2317     0,                                                  /* tp_setattro */
2318     0,                                                  /* tp_as_buffer */
2319     Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
2320     kqueue_queue_doc,                                   /* tp_doc */
2321     0,                                                  /* tp_traverse */
2322     0,                                                  /* tp_clear */
2323     0,                                                  /* tp_richcompare */
2324     0,                                                  /* tp_weaklistoffset */
2325     0,                                                  /* tp_iter */
2326     0,                                                  /* tp_iternext */
2327     kqueue_queue_methods,                               /* tp_methods */
2328     0,                                                  /* tp_members */
2329     kqueue_queue_getsetlist,                            /* tp_getset */
2330     0,                                                  /* tp_base */
2331     0,                                                  /* tp_dict */
2332     0,                                                  /* tp_descr_get */
2333     0,                                                  /* tp_descr_set */
2334     0,                                                  /* tp_dictoffset */
2335     0,                                                  /* tp_init */
2336     0,                                                  /* tp_alloc */
2337     kqueue_queue_new,                                   /* tp_new */
2338     0,                                                  /* tp_free */
2339 };
2340 
2341 #endif /* HAVE_KQUEUE */
2342 
2343 
2344 
2345 
2346 
2347 /* ************************************************************************ */
2348 
2349 PyDoc_STRVAR(select_doc,
2350 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2351 \n\
2352 Wait until one or more file descriptors are ready for some kind of I/O.\n\
2353 The first three arguments are sequences of file descriptors to be waited for:\n\
2354 rlist -- wait until ready for reading\n\
2355 wlist -- wait until ready for writing\n\
2356 xlist -- wait for an ``exceptional condition''\n\
2357 If only one kind of condition is required, pass [] for the other lists.\n\
2358 A file descriptor is either a socket or file object, or a small integer\n\
2359 gotten from a fileno() method call on one of those.\n\
2360 \n\
2361 The optional 4th argument specifies a timeout in seconds; it may be\n\
2362 a floating point number to specify fractions of seconds.  If it is absent\n\
2363 or None, the call will never time out.\n\
2364 \n\
2365 The return value is a tuple of three lists corresponding to the first three\n\
2366 arguments; each contains the subset of the corresponding file descriptors\n\
2367 that are ready.\n\
2368 \n\
2369 *** IMPORTANT NOTICE ***\n\
2370 On Windows, only sockets are supported; on Unix, all file\n\
2371 descriptors can be used.");
2372 
2373 static PyMethodDef select_methods[] = {
2374     {"select",          select_select,  METH_VARARGS,   select_doc},
2375 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2376     {"poll",            select_poll,    METH_NOARGS,    poll_doc},
2377 #endif /* HAVE_POLL */
2378 #ifdef HAVE_SYS_DEVPOLL_H
2379     {"devpoll",         select_devpoll, METH_NOARGS,    devpoll_doc},
2380 #endif
2381     {0,         0},     /* sentinel */
2382 };
2383 
2384 PyDoc_STRVAR(module_doc,
2385 "This module supports asynchronous I/O on multiple file descriptors.\n\
2386 \n\
2387 *** IMPORTANT NOTICE ***\n\
2388 On Windows, only sockets are supported; on Unix, all file descriptors.");
2389 
2390 
2391 static struct PyModuleDef selectmodule = {
2392     PyModuleDef_HEAD_INIT,
2393     "select",
2394     module_doc,
2395     -1,
2396     select_methods,
2397     NULL,
2398     NULL,
2399     NULL,
2400     NULL
2401 };
2402 
2403 
2404 
2405 
2406 PyMODINIT_FUNC
PyInit_select(void)2407 PyInit_select(void)
2408 {
2409     PyObject *m;
2410     m = PyModule_Create(&selectmodule);
2411     if (m == NULL)
2412         return NULL;
2413 
2414     Py_INCREF(PyExc_OSError);
2415     PyModule_AddObject(m, "error", PyExc_OSError);
2416 
2417 #ifdef PIPE_BUF
2418 #ifdef HAVE_BROKEN_PIPE_BUF
2419 #undef PIPE_BUF
2420 #define PIPE_BUF 512
2421 #endif
2422     PyModule_AddIntMacro(m, PIPE_BUF);
2423 #endif
2424 
2425 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2426 #ifdef __APPLE__
2427     if (select_have_broken_poll()) {
2428         if (PyObject_DelAttrString(m, "poll") == -1) {
2429             PyErr_Clear();
2430         }
2431     } else {
2432 #else
2433     {
2434 #endif
2435         if (PyType_Ready(&poll_Type) < 0)
2436             return NULL;
2437         PyModule_AddIntMacro(m, POLLIN);
2438         PyModule_AddIntMacro(m, POLLPRI);
2439         PyModule_AddIntMacro(m, POLLOUT);
2440         PyModule_AddIntMacro(m, POLLERR);
2441         PyModule_AddIntMacro(m, POLLHUP);
2442         PyModule_AddIntMacro(m, POLLNVAL);
2443 
2444 #ifdef POLLRDNORM
2445         PyModule_AddIntMacro(m, POLLRDNORM);
2446 #endif
2447 #ifdef POLLRDBAND
2448         PyModule_AddIntMacro(m, POLLRDBAND);
2449 #endif
2450 #ifdef POLLWRNORM
2451         PyModule_AddIntMacro(m, POLLWRNORM);
2452 #endif
2453 #ifdef POLLWRBAND
2454         PyModule_AddIntMacro(m, POLLWRBAND);
2455 #endif
2456 #ifdef POLLMSG
2457         PyModule_AddIntMacro(m, POLLMSG);
2458 #endif
2459 #ifdef POLLRDHUP
2460         /* Kernel 2.6.17+ */
2461         PyModule_AddIntMacro(m, POLLRDHUP);
2462 #endif
2463     }
2464 #endif /* HAVE_POLL */
2465 
2466 #ifdef HAVE_SYS_DEVPOLL_H
2467     if (PyType_Ready(&devpoll_Type) < 0)
2468         return NULL;
2469 #endif
2470 
2471 #ifdef HAVE_EPOLL
2472     Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2473     if (PyType_Ready(&pyEpoll_Type) < 0)
2474         return NULL;
2475 
2476     Py_INCREF(&pyEpoll_Type);
2477     PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
2478 
2479     PyModule_AddIntMacro(m, EPOLLIN);
2480     PyModule_AddIntMacro(m, EPOLLOUT);
2481     PyModule_AddIntMacro(m, EPOLLPRI);
2482     PyModule_AddIntMacro(m, EPOLLERR);
2483     PyModule_AddIntMacro(m, EPOLLHUP);
2484 #ifdef EPOLLRDHUP
2485     /* Kernel 2.6.17 */
2486     PyModule_AddIntMacro(m, EPOLLRDHUP);
2487 #endif
2488     PyModule_AddIntMacro(m, EPOLLET);
2489 #ifdef EPOLLONESHOT
2490     /* Kernel 2.6.2+ */
2491     PyModule_AddIntMacro(m, EPOLLONESHOT);
2492 #endif
2493 #ifdef EPOLLEXCLUSIVE
2494     PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2495 #endif
2496 
2497 #ifdef EPOLLRDNORM
2498     PyModule_AddIntMacro(m, EPOLLRDNORM);
2499 #endif
2500 #ifdef EPOLLRDBAND
2501     PyModule_AddIntMacro(m, EPOLLRDBAND);
2502 #endif
2503 #ifdef EPOLLWRNORM
2504     PyModule_AddIntMacro(m, EPOLLWRNORM);
2505 #endif
2506 #ifdef EPOLLWRBAND
2507     PyModule_AddIntMacro(m, EPOLLWRBAND);
2508 #endif
2509 #ifdef EPOLLMSG
2510     PyModule_AddIntMacro(m, EPOLLMSG);
2511 #endif
2512 
2513 #ifdef EPOLL_CLOEXEC
2514     PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
2515 #endif
2516 #endif /* HAVE_EPOLL */
2517 
2518 #ifdef HAVE_KQUEUE
2519     kqueue_event_Type.tp_new = PyType_GenericNew;
2520     Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2521     if(PyType_Ready(&kqueue_event_Type) < 0)
2522         return NULL;
2523 
2524     Py_INCREF(&kqueue_event_Type);
2525     PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
2526 
2527     Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2528     if(PyType_Ready(&kqueue_queue_Type) < 0)
2529         return NULL;
2530     Py_INCREF(&kqueue_queue_Type);
2531     PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2532 
2533     /* event filters */
2534     PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2535     PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2536 #ifdef EVFILT_AIO
2537     PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2538 #endif
2539 #ifdef EVFILT_VNODE
2540     PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2541 #endif
2542 #ifdef EVFILT_PROC
2543     PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
2544 #endif
2545 #ifdef EVFILT_NETDEV
2546     PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
2547 #endif
2548 #ifdef EVFILT_SIGNAL
2549     PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2550 #endif
2551     PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
2552 
2553     /* event flags */
2554     PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2555     PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2556     PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2557     PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2558     PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2559     PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
2560 
2561 #ifdef EV_SYSFLAGS
2562     PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2563 #endif
2564 #ifdef EV_FLAG1
2565     PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
2566 #endif
2567 
2568     PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2569     PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
2570 
2571     /* READ WRITE filter flag */
2572 #ifdef NOTE_LOWAT
2573     PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
2574 #endif
2575 
2576     /* VNODE filter flags  */
2577 #ifdef EVFILT_VNODE
2578     PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2579     PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2580     PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2581     PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2582     PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2583     PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2584     PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
2585 #endif
2586 
2587     /* PROC filter flags  */
2588 #ifdef EVFILT_PROC
2589     PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2590     PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2591     PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2592     PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2593     PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
2594 
2595     PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2596     PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2597     PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2598 #endif
2599 
2600     /* NETDEV filter flags */
2601 #ifdef EVFILT_NETDEV
2602     PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2603     PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2604     PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
2605 #endif
2606 
2607 #endif /* HAVE_KQUEUE */
2608     return m;
2609 }
2610