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    Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6    >= 0.
7 */
8 
9 #include "Python.h"
10 #include <structmember.h>
11 
12 #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 
19 /* 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
27 #endif
28 
29 #if defined(HAVE_POLL_H)
30 #include <poll.h>
31 #elif defined(HAVE_SYS_POLL_H)
32 #include <sys/poll.h>
33 #endif
34 
35 #ifdef __sgi
36 /* This is missing from unistd.h */
37 extern void bzero(void *, int);
38 #endif
39 
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>
42 #endif
43 
44 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
45 #include <sys/time.h>
46 #include <utils.h>
47 #endif
48 
49 #ifdef MS_WINDOWS
50 #  include <winsock2.h>
51 #else
52 #  define SOCKET int
53 #  ifdef __BEOS__
54 #    include <net/socket.h>
55 #  elif defined(__VMS)
56 #    include <socket.h>
57 #  endif
58 #endif
59 
60 static PyObject *SelectError;
61 
62 /* list of Python objects and their file descriptor */
63 typedef struct {
64     PyObject *obj;                           /* owned reference */
65     SOCKET fd;
66     int sentinel;                            /* -1 == sentinel */
67 } pylist;
68 
69 static void
reap_obj(pylist fd2obj[FD_SETSIZE+1])70 reap_obj(pylist fd2obj[FD_SETSIZE + 1])
71 {
72     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;
78 }
79 
80 
81 /* returns -1 and sets the Python exception if an error occurred, otherwise
82    returns a number >= 0
83 */
84 static int
seq2set(PyObject * seq,fd_set * set,pylist fd2obj[FD_SETSIZE+1])85 seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
86 {
87     int i;
88     int max = -1;
89     int index = 0;
90     int len = -1;
91     PyObject* fast_seq = NULL;
92     PyObject* o = NULL;
93 
94     fd2obj[0].obj = (PyObject*)0;            /* set list to zero size */
95     FD_ZERO(set);
96 
97     fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
98     if (!fast_seq)
99         return -1;
100 
101     len = PySequence_Fast_GET_SIZE(fast_seq);
102 
103     for (i = 0; i < len; i++)  {
104         SOCKET v;
105 
106         /* any intervening fileno() calls could decr this refcnt */
107         if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
108             return -1;
109 
110         Py_INCREF(o);
111         v = PyObject_AsFileDescriptor( o );
112         if (v == -1) goto finally;
113 
114 #if defined(_MSC_VER) && !defined(UEFI_C_SOURCE)
115         max = 0;                             /* not used for Win32 */
116 #else  /* !_MSC_VER */
117         if (v < 0 || v >= FD_SETSIZE) {
118             PyErr_SetString(PyExc_ValueError,
119                         "filedescriptor out of range in select()");
120             goto finally;
121         }
122         if (v > max)
123             max = v;
124 #endif /* _MSC_VER */
125         FD_SET(v, set);
126 
127         /* add object and its file descriptor to the list */
128         if (index >= FD_SETSIZE) {
129             PyErr_SetString(PyExc_ValueError,
130                           "too many file descriptors in select()");
131             goto finally;
132         }
133         fd2obj[index].obj = o;
134         fd2obj[index].fd = v;
135         fd2obj[index].sentinel = 0;
136         fd2obj[++index].sentinel = -1;
137     }
138     Py_DECREF(fast_seq);
139     return max+1;
140 
141   finally:
142     Py_XDECREF(o);
143     Py_DECREF(fast_seq);
144     return -1;
145 }
146 
147 /* returns NULL and sets the Python exception if an error occurred */
148 static PyObject *
set2list(fd_set * set,pylist fd2obj[FD_SETSIZE+1])149 set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
150 {
151     int i, j, count=0;
152     PyObject *list, *o;
153     SOCKET fd;
154 
155     for (j = 0; fd2obj[j].sentinel >= 0; j++) {
156         if (FD_ISSET(fd2obj[j].fd, set))
157             count++;
158     }
159     list = PyList_New(count);
160     if (!list)
161         return NULL;
162 
163     i = 0;
164     for (j = 0; fd2obj[j].sentinel >= 0; j++) {
165         fd = fd2obj[j].fd;
166         if (FD_ISSET(fd, set)) {
167 #if !defined(_MSC_VER) || defined(UEFI_C_SOURCE)
168             if (fd > FD_SETSIZE) {
169                 PyErr_SetString(PyExc_SystemError,
170                "filedescriptor out of range returned in select()");
171                 goto finally;
172             }
173 #endif
174             o = fd2obj[j].obj;
175             fd2obj[j].obj = NULL;
176             /* transfer ownership */
177             if (PyList_SetItem(list, i, o) < 0)
178                 goto finally;
179 
180             i++;
181         }
182     }
183     return list;
184   finally:
185     Py_DECREF(list);
186     return NULL;
187 }
188 
189 #undef SELECT_USES_HEAP
190 #if FD_SETSIZE > 1024
191 #define SELECT_USES_HEAP
192 #endif /* FD_SETSIZE > 1024 */
193 
194 static PyObject *
select_select(PyObject * self,PyObject * args)195 select_select(PyObject *self, PyObject *args)
196 {
197 #ifdef SELECT_USES_HEAP
198     pylist *rfd2obj, *wfd2obj, *efd2obj;
199 #else  /* !SELECT_USES_HEAP */
200     /* XXX: All this should probably be implemented as follows:
201      * - find the highest descriptor we're interested in
202      * - add one
203      * - that's the size
204      * See: Stevens, APitUE, $12.5.1
205      */
206     pylist rfd2obj[FD_SETSIZE + 1];
207     pylist wfd2obj[FD_SETSIZE + 1];
208     pylist efd2obj[FD_SETSIZE + 1];
209 #endif /* SELECT_USES_HEAP */
210     PyObject *ifdlist, *ofdlist, *efdlist;
211     PyObject *ret = NULL;
212     PyObject *tout = Py_None;
213     fd_set ifdset, ofdset, efdset;
214     double timeout;
215     struct timeval tv, *tvp;
216     long seconds;
217     int imax, omax, emax, max;
218     int n;
219 
220     /* convert arguments */
221     if (!PyArg_UnpackTuple(args, "select", 3, 4,
222                           &ifdlist, &ofdlist, &efdlist, &tout))
223         return NULL;
224 
225     if (tout == Py_None)
226         tvp = (struct timeval *)0;
227     else if (!PyNumber_Check(tout)) {
228         PyErr_SetString(PyExc_TypeError,
229                         "timeout must be a float or None");
230         return NULL;
231     }
232     else {
233         timeout = PyFloat_AsDouble(tout);
234         if (timeout == -1 && PyErr_Occurred())
235             return NULL;
236         if (timeout > (double)LONG_MAX) {
237             PyErr_SetString(PyExc_OverflowError,
238                             "timeout period too long");
239             return NULL;
240         }
241         seconds = (long)timeout;
242         timeout = timeout - (double)seconds;
243         tv.tv_sec = seconds;
244         tv.tv_usec = (long)(timeout * 1E6);
245         tvp = &tv;
246     }
247 
248 
249 #ifdef SELECT_USES_HEAP
250     /* Allocate memory for the lists */
251     rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252     wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253     efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254     if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
255         if (rfd2obj) PyMem_DEL(rfd2obj);
256         if (wfd2obj) PyMem_DEL(wfd2obj);
257         if (efd2obj) PyMem_DEL(efd2obj);
258         return PyErr_NoMemory();
259     }
260 #endif /* SELECT_USES_HEAP */
261     /* Convert sequences to fd_sets, and get maximum fd number
262      * propagates the Python exception set in seq2set()
263      */
264     rfd2obj[0].sentinel = -1;
265     wfd2obj[0].sentinel = -1;
266     efd2obj[0].sentinel = -1;
267     if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
268         goto finally;
269     if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
270         goto finally;
271     if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
272         goto finally;
273     max = imax;
274     if (omax > max) max = omax;
275     if (emax > max) max = emax;
276 
277     Py_BEGIN_ALLOW_THREADS
278     n = select(max, &ifdset, &ofdset, &efdset, tvp);
279     Py_END_ALLOW_THREADS
280 
281 #ifdef MS_WINDOWS
282     if (n == SOCKET_ERROR) {
283         PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
284     }
285 #else
286     if (n < 0) {
287         PyErr_SetFromErrno(SelectError);
288     }
289 #endif
290     else {
291         /* any of these three calls can raise an exception.  it's more
292            convenient to test for this after all three calls... but
293            is that acceptable?
294         */
295         ifdlist = set2list(&ifdset, rfd2obj);
296         ofdlist = set2list(&ofdset, wfd2obj);
297         efdlist = set2list(&efdset, efd2obj);
298         if (PyErr_Occurred())
299             ret = NULL;
300         else
301             ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
302 
303         Py_DECREF(ifdlist);
304         Py_DECREF(ofdlist);
305         Py_DECREF(efdlist);
306     }
307 
308   finally:
309     reap_obj(rfd2obj);
310     reap_obj(wfd2obj);
311     reap_obj(efd2obj);
312 #ifdef SELECT_USES_HEAP
313     PyMem_DEL(rfd2obj);
314     PyMem_DEL(wfd2obj);
315     PyMem_DEL(efd2obj);
316 #endif /* SELECT_USES_HEAP */
317     return ret;
318 }
319 
320 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
321 /*
322  * poll() support
323  */
324 
325 typedef struct {
326     PyObject_HEAD
327     PyObject *dict;
328     int ufd_uptodate;
329     int ufd_len;
330     struct pollfd *ufds;
331 } pollObject;
332 
333 static PyTypeObject poll_Type;
334 
335 /* Update the malloc'ed array of pollfds to match the dictionary
336    contained within a pollObject.  Return 1 on success, 0 on an error.
337 */
338 
339 static int
update_ufd_array(pollObject * self)340 update_ufd_array(pollObject *self)
341 {
342     Py_ssize_t i, pos;
343     PyObject *key, *value;
344     struct pollfd *old_ufds = self->ufds;
345 
346     self->ufd_len = PyDict_Size(self->dict);
347     PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
348     if (self->ufds == NULL) {
349         self->ufds = old_ufds;
350         PyErr_NoMemory();
351         return 0;
352     }
353 
354     i = pos = 0;
355     while (PyDict_Next(self->dict, &pos, &key, &value)) {
356         self->ufds[i].fd = PyInt_AsLong(key);
357         self->ufds[i].events = (short)PyInt_AsLong(value);
358         i++;
359     }
360     self->ufd_uptodate = 1;
361     return 1;
362 }
363 
364 PyDoc_STRVAR(poll_register_doc,
365 "register(fd [, eventmask] ) -> None\n\n\
366 Register a file descriptor with the polling object.\n\
367 fd -- either an integer, or an object with a fileno() method returning an\n\
368       int.\n\
369 events -- an optional bitmask describing the type of events to check for");
370 
371 static PyObject *
poll_register(pollObject * self,PyObject * args)372 poll_register(pollObject *self, PyObject *args)
373 {
374     PyObject *o, *key, *value;
375     int fd, events = POLLIN | POLLPRI | POLLOUT;
376     int err;
377 
378     if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
379         return NULL;
380     }
381 
382     fd = PyObject_AsFileDescriptor(o);
383     if (fd == -1) return NULL;
384 
385     /* Add entry to the internal dictionary: the key is the
386        file descriptor, and the value is the event mask. */
387     key = PyInt_FromLong(fd);
388     if (key == NULL)
389         return NULL;
390     value = PyInt_FromLong(events);
391     if (value == NULL) {
392         Py_DECREF(key);
393         return NULL;
394     }
395     err = PyDict_SetItem(self->dict, key, value);
396     Py_DECREF(key);
397     Py_DECREF(value);
398     if (err < 0)
399         return NULL;
400 
401     self->ufd_uptodate = 0;
402 
403     Py_INCREF(Py_None);
404     return Py_None;
405 }
406 
407 PyDoc_STRVAR(poll_modify_doc,
408 "modify(fd, eventmask) -> None\n\n\
409 Modify an already registered file descriptor.\n\
410 fd -- either an integer, or an object with a fileno() method returning an\n\
411       int.\n\
412 events -- an optional bitmask describing the type of events to check for");
413 
414 static PyObject *
poll_modify(pollObject * self,PyObject * args)415 poll_modify(pollObject *self, PyObject *args)
416 {
417     PyObject *o, *key, *value;
418     int fd, events;
419     int err;
420 
421     if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
422         return NULL;
423     }
424 
425     fd = PyObject_AsFileDescriptor(o);
426     if (fd == -1) return NULL;
427 
428     /* Modify registered fd */
429     key = PyInt_FromLong(fd);
430     if (key == NULL)
431         return NULL;
432     if (PyDict_GetItem(self->dict, key) == NULL) {
433         errno = ENOENT;
434         PyErr_SetFromErrno(PyExc_IOError);
435         return NULL;
436     }
437     value = PyInt_FromLong(events);
438     if (value == NULL) {
439         Py_DECREF(key);
440         return NULL;
441     }
442     err = PyDict_SetItem(self->dict, key, value);
443     Py_DECREF(key);
444     Py_DECREF(value);
445     if (err < 0)
446         return NULL;
447 
448     self->ufd_uptodate = 0;
449 
450     Py_INCREF(Py_None);
451     return Py_None;
452 }
453 
454 
455 PyDoc_STRVAR(poll_unregister_doc,
456 "unregister(fd) -> None\n\n\
457 Remove a file descriptor being tracked by the polling object.");
458 
459 static PyObject *
poll_unregister(pollObject * self,PyObject * o)460 poll_unregister(pollObject *self, PyObject *o)
461 {
462     PyObject *key;
463     int fd;
464 
465     fd = PyObject_AsFileDescriptor( o );
466     if (fd == -1)
467         return NULL;
468 
469     /* Check whether the fd is already in the array */
470     key = PyInt_FromLong(fd);
471     if (key == NULL)
472         return NULL;
473 
474     if (PyDict_DelItem(self->dict, key) == -1) {
475         Py_DECREF(key);
476         /* This will simply raise the KeyError set by PyDict_DelItem
477            if the file descriptor isn't registered. */
478         return NULL;
479     }
480 
481     Py_DECREF(key);
482     self->ufd_uptodate = 0;
483 
484     Py_INCREF(Py_None);
485     return Py_None;
486 }
487 
488 PyDoc_STRVAR(poll_poll_doc,
489 "poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
490 Polls the set of registered file descriptors, returning a list containing \n\
491 any descriptors that have events or errors to report.");
492 
493 static PyObject *
poll_poll(pollObject * self,PyObject * args)494 poll_poll(pollObject *self, PyObject *args)
495 {
496     PyObject *result_list = NULL, *tout = NULL;
497     int timeout = 0, poll_result, i, j;
498     PyObject *value = NULL, *num = NULL;
499 
500     if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
501         return NULL;
502     }
503 
504     /* Check values for timeout */
505     if (tout == NULL || tout == Py_None)
506         timeout = -1;
507     else if (!PyNumber_Check(tout)) {
508         PyErr_SetString(PyExc_TypeError,
509                         "timeout must be an integer or None");
510         return NULL;
511     }
512     else {
513         tout = PyNumber_Int(tout);
514         if (!tout)
515             return NULL;
516         timeout = PyInt_AsLong(tout);
517         Py_DECREF(tout);
518         if (timeout == -1 && PyErr_Occurred())
519             return NULL;
520     }
521 
522     /* Ensure the ufd array is up to date */
523     if (!self->ufd_uptodate)
524         if (update_ufd_array(self) == 0)
525             return NULL;
526 
527     /* call poll() */
528     Py_BEGIN_ALLOW_THREADS
529     poll_result = poll(self->ufds, self->ufd_len, timeout);
530     Py_END_ALLOW_THREADS
531 
532     if (poll_result < 0) {
533         PyErr_SetFromErrno(SelectError);
534         return NULL;
535     }
536 
537     /* build the result list */
538 
539     result_list = PyList_New(poll_result);
540     if (!result_list)
541         return NULL;
542     else {
543         for (i = 0, j = 0; j < poll_result; j++) {
544             /* skip to the next fired descriptor */
545             while (!self->ufds[i].revents) {
546                 i++;
547             }
548             /* if we hit a NULL return, set value to NULL
549                and break out of loop; code at end will
550                clean up result_list */
551             value = PyTuple_New(2);
552             if (value == NULL)
553                 goto error;
554             num = PyInt_FromLong(self->ufds[i].fd);
555             if (num == NULL) {
556                 Py_DECREF(value);
557                 goto error;
558             }
559             PyTuple_SET_ITEM(value, 0, num);
560 
561             /* The &0xffff is a workaround for AIX.  'revents'
562                is a 16-bit short, and IBM assigned POLLNVAL
563                to be 0x8000, so the conversion to int results
564                in a negative number. See SF bug #923315. */
565             num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
566             if (num == NULL) {
567                 Py_DECREF(value);
568                 goto error;
569             }
570             PyTuple_SET_ITEM(value, 1, num);
571             if ((PyList_SetItem(result_list, j, value)) == -1) {
572                 Py_DECREF(value);
573                 goto error;
574             }
575             i++;
576         }
577     }
578     return result_list;
579 
580   error:
581     Py_DECREF(result_list);
582     return NULL;
583 }
584 
585 static PyMethodDef poll_methods[] = {
586     {"register",        (PyCFunction)poll_register,
587      METH_VARARGS,  poll_register_doc},
588     {"modify",          (PyCFunction)poll_modify,
589      METH_VARARGS,  poll_modify_doc},
590     {"unregister",      (PyCFunction)poll_unregister,
591      METH_O,        poll_unregister_doc},
592     {"poll",            (PyCFunction)poll_poll,
593      METH_VARARGS,  poll_poll_doc},
594     {NULL,              NULL}           /* sentinel */
595 };
596 
597 static pollObject *
newPollObject(void)598 newPollObject(void)
599 {
600     pollObject *self;
601     self = PyObject_New(pollObject, &poll_Type);
602     if (self == NULL)
603         return NULL;
604     /* ufd_uptodate is a Boolean, denoting whether the
605        array pointed to by ufds matches the contents of the dictionary. */
606     self->ufd_uptodate = 0;
607     self->ufds = NULL;
608     self->dict = PyDict_New();
609     if (self->dict == NULL) {
610         Py_DECREF(self);
611         return NULL;
612     }
613     return self;
614 }
615 
616 static void
poll_dealloc(pollObject * self)617 poll_dealloc(pollObject *self)
618 {
619     if (self->ufds != NULL)
620         PyMem_DEL(self->ufds);
621     Py_XDECREF(self->dict);
622     PyObject_Del(self);
623 }
624 
625 static PyObject *
poll_getattr(pollObject * self,char * name)626 poll_getattr(pollObject *self, char *name)
627 {
628     return Py_FindMethod(poll_methods, (PyObject *)self, name);
629 }
630 
631 static PyTypeObject poll_Type = {
632     /* The ob_type field must be initialized in the module init function
633      * to be portable to Windows without using C++. */
634     PyVarObject_HEAD_INIT(NULL, 0)
635     "select.poll",              /*tp_name*/
636     sizeof(pollObject),         /*tp_basicsize*/
637     0,                          /*tp_itemsize*/
638     /* methods */
639     (destructor)poll_dealloc, /*tp_dealloc*/
640     0,                          /*tp_print*/
641     (getattrfunc)poll_getattr, /*tp_getattr*/
642     0,                      /*tp_setattr*/
643     0,                          /*tp_compare*/
644     0,                          /*tp_repr*/
645     0,                          /*tp_as_number*/
646     0,                          /*tp_as_sequence*/
647     0,                          /*tp_as_mapping*/
648     0,                          /*tp_hash*/
649 };
650 
651 PyDoc_STRVAR(poll_doc,
652 "Returns a polling object, which supports registering and\n\
653 unregistering file descriptors, and then polling them for I/O events.");
654 
655 static PyObject *
select_poll(PyObject * self,PyObject * unused)656 select_poll(PyObject *self, PyObject *unused)
657 {
658     return (PyObject *)newPollObject();
659 }
660 
661 #ifdef __APPLE__
662 /*
663  * On some systems poll() sets errno on invalid file descriptors. We test
664  * for this at runtime because this bug may be fixed or introduced between
665  * OS releases.
666  */
select_have_broken_poll(void)667 static int select_have_broken_poll(void)
668 {
669     int poll_test;
670     int filedes[2];
671 
672     struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
673 
674     /* Create a file descriptor to make invalid */
675     if (pipe(filedes) < 0) {
676         return 1;
677     }
678     poll_struct.fd = filedes[0];
679     close(filedes[0]);
680     close(filedes[1]);
681     poll_test = poll(&poll_struct, 1, 0);
682     if (poll_test < 0) {
683         return 1;
684     } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
685         return 1;
686     }
687     return 0;
688 }
689 #endif /* __APPLE__ */
690 
691 #endif /* HAVE_POLL */
692 
693 #ifdef HAVE_EPOLL
694 /* **************************************************************************
695  *                      epoll interface for Linux 2.6
696  *
697  * Written by Christian Heimes
698  * Inspired by Twisted's _epoll.pyx and select.poll()
699  */
700 
701 #ifdef HAVE_SYS_EPOLL_H
702 #include <sys/epoll.h>
703 #endif
704 
705 typedef struct {
706     PyObject_HEAD
707     SOCKET epfd;                        /* epoll control file descriptor */
708 } pyEpoll_Object;
709 
710 static PyTypeObject pyEpoll_Type;
711 #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
712 
713 static PyObject *
pyepoll_err_closed(void)714 pyepoll_err_closed(void)
715 {
716     PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
717     return NULL;
718 }
719 
720 static int
pyepoll_internal_close(pyEpoll_Object * self)721 pyepoll_internal_close(pyEpoll_Object *self)
722 {
723     int save_errno = 0;
724     if (self->epfd >= 0) {
725         int epfd = self->epfd;
726         self->epfd = -1;
727         Py_BEGIN_ALLOW_THREADS
728         if (close(epfd) < 0)
729             save_errno = errno;
730         Py_END_ALLOW_THREADS
731     }
732     return save_errno;
733 }
734 
735 static PyObject *
newPyEpoll_Object(PyTypeObject * type,int sizehint,SOCKET fd)736 newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
737 {
738     pyEpoll_Object *self;
739 
740     if (sizehint == -1) {
741         sizehint = FD_SETSIZE-1;
742     }
743     else if (sizehint < 1) {
744         PyErr_Format(PyExc_ValueError,
745                      "sizehint must be greater zero, got %d",
746                      sizehint);
747         return NULL;
748     }
749 
750     assert(type != NULL && type->tp_alloc != NULL);
751     self = (pyEpoll_Object *) type->tp_alloc(type, 0);
752     if (self == NULL)
753         return NULL;
754 
755     if (fd == -1) {
756         Py_BEGIN_ALLOW_THREADS
757         self->epfd = epoll_create(sizehint);
758         Py_END_ALLOW_THREADS
759     }
760     else {
761         self->epfd = fd;
762     }
763     if (self->epfd < 0) {
764         Py_DECREF(self);
765         PyErr_SetFromErrno(PyExc_IOError);
766         return NULL;
767     }
768     return (PyObject *)self;
769 }
770 
771 
772 static PyObject *
pyepoll_new(PyTypeObject * type,PyObject * args,PyObject * kwds)773 pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
774 {
775     int sizehint = -1;
776     static char *kwlist[] = {"sizehint", NULL};
777 
778     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
779                                      &sizehint))
780         return NULL;
781 
782     return newPyEpoll_Object(type, sizehint, -1);
783 }
784 
785 
786 static void
pyepoll_dealloc(pyEpoll_Object * self)787 pyepoll_dealloc(pyEpoll_Object *self)
788 {
789     (void)pyepoll_internal_close(self);
790     Py_TYPE(self)->tp_free(self);
791 }
792 
793 static PyObject*
pyepoll_close(pyEpoll_Object * self)794 pyepoll_close(pyEpoll_Object *self)
795 {
796     errno = pyepoll_internal_close(self);
797     if (errno < 0) {
798         PyErr_SetFromErrno(PyExc_IOError);
799         return NULL;
800     }
801     Py_RETURN_NONE;
802 }
803 
804 PyDoc_STRVAR(pyepoll_close_doc,
805 "close() -> None\n\
806 \n\
807 Close the epoll control file descriptor. Further operations on the epoll\n\
808 object will raise an exception.");
809 
810 static PyObject*
pyepoll_get_closed(pyEpoll_Object * self)811 pyepoll_get_closed(pyEpoll_Object *self)
812 {
813     if (self->epfd < 0)
814         Py_RETURN_TRUE;
815     else
816         Py_RETURN_FALSE;
817 }
818 
819 static PyObject*
pyepoll_fileno(pyEpoll_Object * self)820 pyepoll_fileno(pyEpoll_Object *self)
821 {
822     if (self->epfd < 0)
823         return pyepoll_err_closed();
824     return PyInt_FromLong(self->epfd);
825 }
826 
827 PyDoc_STRVAR(pyepoll_fileno_doc,
828 "fileno() -> int\n\
829 \n\
830 Return the epoll control file descriptor.");
831 
832 static PyObject*
pyepoll_fromfd(PyObject * cls,PyObject * args)833 pyepoll_fromfd(PyObject *cls, PyObject *args)
834 {
835     SOCKET fd;
836 
837     if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
838         return NULL;
839 
840     return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
841 }
842 
843 PyDoc_STRVAR(pyepoll_fromfd_doc,
844 "fromfd(fd) -> epoll\n\
845 \n\
846 Create an epoll object from a given control fd.");
847 
848 static PyObject *
pyepoll_internal_ctl(int epfd,int op,PyObject * pfd,unsigned int events)849 pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
850 {
851     struct epoll_event ev;
852     int result;
853     int fd;
854 
855     if (epfd < 0)
856         return pyepoll_err_closed();
857 
858     fd = PyObject_AsFileDescriptor(pfd);
859     if (fd == -1) {
860         return NULL;
861     }
862 
863     switch(op) {
864         case EPOLL_CTL_ADD:
865         case EPOLL_CTL_MOD:
866         ev.events = events;
867         ev.data.fd = fd;
868         Py_BEGIN_ALLOW_THREADS
869         result = epoll_ctl(epfd, op, fd, &ev);
870         Py_END_ALLOW_THREADS
871         break;
872         case EPOLL_CTL_DEL:
873         /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
874          * operation required a non-NULL pointer in event, even
875          * though this argument is ignored. */
876         Py_BEGIN_ALLOW_THREADS
877         result = epoll_ctl(epfd, op, fd, &ev);
878         if (errno == EBADF) {
879             /* fd already closed */
880             result = 0;
881             errno = 0;
882         }
883         Py_END_ALLOW_THREADS
884         break;
885         default:
886         result = -1;
887         errno = EINVAL;
888     }
889 
890     if (result < 0) {
891         PyErr_SetFromErrno(PyExc_IOError);
892         return NULL;
893     }
894     Py_RETURN_NONE;
895 }
896 
897 static PyObject *
pyepoll_register(pyEpoll_Object * self,PyObject * args,PyObject * kwds)898 pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
899 {
900     PyObject *pfd;
901     unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
902     static char *kwlist[] = {"fd", "eventmask", NULL};
903 
904     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
905                                      &pfd, &events)) {
906         return NULL;
907     }
908 
909     return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
910 }
911 
912 PyDoc_STRVAR(pyepoll_register_doc,
913 "register(fd[, eventmask]) -> None\n\
914 \n\
915 Registers a new fd or modifies an already registered fd.\n\
916 fd is the target file descriptor of the operation.\n\
917 events is a bit set composed of the various EPOLL constants; the default\n\
918 is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
919 \n\
920 The epoll interface supports all file descriptors that support poll.");
921 
922 static PyObject *
pyepoll_modify(pyEpoll_Object * self,PyObject * args,PyObject * kwds)923 pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
924 {
925     PyObject *pfd;
926     unsigned int events;
927     static char *kwlist[] = {"fd", "eventmask", NULL};
928 
929     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
930                                      &pfd, &events)) {
931         return NULL;
932     }
933 
934     return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
935 }
936 
937 PyDoc_STRVAR(pyepoll_modify_doc,
938 "modify(fd, eventmask) -> None\n\
939 \n\
940 fd is the target file descriptor of the operation\n\
941 events is a bit set composed of the various EPOLL constants");
942 
943 static PyObject *
pyepoll_unregister(pyEpoll_Object * self,PyObject * args,PyObject * kwds)944 pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
945 {
946     PyObject *pfd;
947     static char *kwlist[] = {"fd", NULL};
948 
949     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
950                                      &pfd)) {
951         return NULL;
952     }
953 
954     return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
955 }
956 
957 PyDoc_STRVAR(pyepoll_unregister_doc,
958 "unregister(fd) -> None\n\
959 \n\
960 fd is the target file descriptor of the operation.");
961 
962 static PyObject *
pyepoll_poll(pyEpoll_Object * self,PyObject * args,PyObject * kwds)963 pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
964 {
965     double dtimeout = -1.;
966     int timeout;
967     int maxevents = -1;
968     int nfds, i;
969     PyObject *elist = NULL, *etuple = NULL;
970     struct epoll_event *evs = NULL;
971     static char *kwlist[] = {"timeout", "maxevents", NULL};
972 
973     if (self->epfd < 0)
974         return pyepoll_err_closed();
975 
976     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
977                                      &dtimeout, &maxevents)) {
978         return NULL;
979     }
980 
981     if (dtimeout < 0) {
982         timeout = -1;
983     }
984     else if (dtimeout * 1000.0 > INT_MAX) {
985         PyErr_SetString(PyExc_OverflowError,
986                         "timeout is too large");
987         return NULL;
988     }
989     else {
990         timeout = (int)(dtimeout * 1000.0);
991     }
992 
993     if (maxevents == -1) {
994         maxevents = FD_SETSIZE-1;
995     }
996     else if (maxevents < 1) {
997         PyErr_Format(PyExc_ValueError,
998                      "maxevents must be greater than 0, got %d",
999                      maxevents);
1000         return NULL;
1001     }
1002 
1003     evs = PyMem_New(struct epoll_event, maxevents);
1004     if (evs == NULL) {
1005         Py_DECREF(self);
1006         PyErr_NoMemory();
1007         return NULL;
1008     }
1009 
1010     Py_BEGIN_ALLOW_THREADS
1011     nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1012     Py_END_ALLOW_THREADS
1013     if (nfds < 0) {
1014         PyErr_SetFromErrno(PyExc_IOError);
1015         goto error;
1016     }
1017 
1018     elist = PyList_New(nfds);
1019     if (elist == NULL) {
1020         goto error;
1021     }
1022 
1023     for (i = 0; i < nfds; i++) {
1024         etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1025         if (etuple == NULL) {
1026             Py_CLEAR(elist);
1027             goto error;
1028         }
1029         PyList_SET_ITEM(elist, i, etuple);
1030     }
1031 
1032     error:
1033     PyMem_Free(evs);
1034     return elist;
1035 }
1036 
1037 PyDoc_STRVAR(pyepoll_poll_doc,
1038 "poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1039 \n\
1040 Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1041 in seconds (as float). -1 makes poll wait indefinitely.\n\
1042 Up to maxevents are returned to the caller.");
1043 
1044 static PyMethodDef pyepoll_methods[] = {
1045     {"fromfd",          (PyCFunction)pyepoll_fromfd,
1046      METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1047     {"close",           (PyCFunction)pyepoll_close,     METH_NOARGS,
1048      pyepoll_close_doc},
1049     {"fileno",          (PyCFunction)pyepoll_fileno,    METH_NOARGS,
1050      pyepoll_fileno_doc},
1051     {"modify",          (PyCFunction)pyepoll_modify,
1052      METH_VARARGS | METH_KEYWORDS,      pyepoll_modify_doc},
1053     {"register",        (PyCFunction)pyepoll_register,
1054      METH_VARARGS | METH_KEYWORDS,      pyepoll_register_doc},
1055     {"unregister",      (PyCFunction)pyepoll_unregister,
1056      METH_VARARGS | METH_KEYWORDS,      pyepoll_unregister_doc},
1057     {"poll",            (PyCFunction)pyepoll_poll,
1058      METH_VARARGS | METH_KEYWORDS,      pyepoll_poll_doc},
1059     {NULL,      NULL},
1060 };
1061 
1062 static PyGetSetDef pyepoll_getsetlist[] = {
1063     {"closed", (getter)pyepoll_get_closed, NULL,
1064      "True if the epoll handler is closed"},
1065     {0},
1066 };
1067 
1068 PyDoc_STRVAR(pyepoll_doc,
1069 "select.epoll([sizehint=-1])\n\
1070 \n\
1071 Returns an epolling object\n\
1072 \n\
1073 sizehint must be a positive integer or -1 for the default size. The\n\
1074 sizehint is used to optimize internal data structures. It doesn't limit\n\
1075 the maximum number of monitored events.");
1076 
1077 static PyTypeObject pyEpoll_Type = {
1078     PyVarObject_HEAD_INIT(NULL, 0)
1079     "select.epoll",                                     /* tp_name */
1080     sizeof(pyEpoll_Object),                             /* tp_basicsize */
1081     0,                                                  /* tp_itemsize */
1082     (destructor)pyepoll_dealloc,                        /* tp_dealloc */
1083     0,                                                  /* tp_print */
1084     0,                                                  /* tp_getattr */
1085     0,                                                  /* tp_setattr */
1086     0,                                                  /* tp_compare */
1087     0,                                                  /* tp_repr */
1088     0,                                                  /* tp_as_number */
1089     0,                                                  /* tp_as_sequence */
1090     0,                                                  /* tp_as_mapping */
1091     0,                                                  /* tp_hash */
1092     0,                                                  /* tp_call */
1093     0,                                                  /* tp_str */
1094     PyObject_GenericGetAttr,                            /* tp_getattro */
1095     0,                                                  /* tp_setattro */
1096     0,                                                  /* tp_as_buffer */
1097     Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
1098     pyepoll_doc,                                        /* tp_doc */
1099     0,                                                  /* tp_traverse */
1100     0,                                                  /* tp_clear */
1101     0,                                                  /* tp_richcompare */
1102     0,                                                  /* tp_weaklistoffset */
1103     0,                                                  /* tp_iter */
1104     0,                                                  /* tp_iternext */
1105     pyepoll_methods,                                    /* tp_methods */
1106     0,                                                  /* tp_members */
1107     pyepoll_getsetlist,                                 /* tp_getset */
1108     0,                                                  /* tp_base */
1109     0,                                                  /* tp_dict */
1110     0,                                                  /* tp_descr_get */
1111     0,                                                  /* tp_descr_set */
1112     0,                                                  /* tp_dictoffset */
1113     0,                                                  /* tp_init */
1114     0,                                                  /* tp_alloc */
1115     pyepoll_new,                                        /* tp_new */
1116     0,                                                  /* tp_free */
1117 };
1118 
1119 #endif /* HAVE_EPOLL */
1120 
1121 #ifdef HAVE_KQUEUE
1122 /* **************************************************************************
1123  *                      kqueue interface for BSD
1124  *
1125  * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1126  * All rights reserved.
1127  *
1128  * Redistribution and use in source and binary forms, with or without
1129  * modification, are permitted provided that the following conditions
1130  * are met:
1131  * 1. Redistributions of source code must retain the above copyright
1132  *    notice, this list of conditions and the following disclaimer.
1133  * 2. Redistributions in binary form must reproduce the above copyright
1134  *    notice, this list of conditions and the following disclaimer in the
1135  *    documentation and/or other materials provided with the distribution.
1136  *
1137  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1138  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1139  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1140  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1141  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1142  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1143  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1144  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1145  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1146  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1147  * SUCH DAMAGE.
1148  */
1149 
1150 #ifdef HAVE_SYS_EVENT_H
1151 #include <sys/event.h>
1152 #endif
1153 
1154 PyDoc_STRVAR(kqueue_event_doc,
1155 "kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
1156 \n\
1157 This object is the equivalent of the struct kevent for the C API.\n\
1158 \n\
1159 See the kqueue manpage for more detailed information about the meaning\n\
1160 of the arguments.\n\
1161 \n\
1162 One minor note: while you might hope that udata could store a\n\
1163 reference to a python object, it cannot, because it is impossible to\n\
1164 keep a proper reference count of the object once it's passed into the\n\
1165 kernel. Therefore, I have restricted it to only storing an integer.  I\n\
1166 recommend ignoring it and simply using the 'ident' field to key off\n\
1167 of. You could also set up a dictionary on the python side to store a\n\
1168 udata->object mapping.");
1169 
1170 typedef struct {
1171     PyObject_HEAD
1172     struct kevent e;
1173 } kqueue_event_Object;
1174 
1175 static PyTypeObject kqueue_event_Type;
1176 
1177 #define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1178 
1179 typedef struct {
1180     PyObject_HEAD
1181     SOCKET kqfd;                /* kqueue control fd */
1182 } kqueue_queue_Object;
1183 
1184 static PyTypeObject kqueue_queue_Type;
1185 
1186 #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1187 
1188 #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1189 #   error uintptr_t does not match void *!
1190 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1191 #   define T_UINTPTRT         T_ULONGLONG
1192 #   define T_INTPTRT          T_LONGLONG
1193 #   define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1194 #   define UINTPTRT_FMT_UNIT  "K"
1195 #   define INTPTRT_FMT_UNIT   "L"
1196 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1197 #   define T_UINTPTRT         T_ULONG
1198 #   define T_INTPTRT          T_LONG
1199 #   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1200 #   define UINTPTRT_FMT_UNIT  "k"
1201 #   define INTPTRT_FMT_UNIT   "l"
1202 #elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1203 #   define T_UINTPTRT         T_UINT
1204 #   define T_INTPTRT          T_INT
1205 #   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1206 #   define UINTPTRT_FMT_UNIT  "I"
1207 #   define INTPTRT_FMT_UNIT   "i"
1208 #else
1209 #   error uintptr_t does not match int, long, or long long!
1210 #endif
1211 
1212 /* Unfortunately, we can't store python objects in udata, because
1213  * kevents in the kernel can be removed without warning, which would
1214  * forever lose the refcount on the object stored with it.
1215  */
1216 
1217 #define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1218 static struct PyMemberDef kqueue_event_members[] = {
1219     {"ident",           T_UINTPTRT,     KQ_OFF(e.ident)},
1220     {"filter",          T_SHORT,        KQ_OFF(e.filter)},
1221     {"flags",           T_USHORT,       KQ_OFF(e.flags)},
1222     {"fflags",          T_UINT,         KQ_OFF(e.fflags)},
1223     {"data",            T_INTPTRT,      KQ_OFF(e.data)},
1224     {"udata",           T_UINTPTRT,     KQ_OFF(e.udata)},
1225     {NULL} /* Sentinel */
1226 };
1227 #undef KQ_OFF
1228 
1229 static PyObject *
1230 
kqueue_event_repr(kqueue_event_Object * s)1231 kqueue_event_repr(kqueue_event_Object *s)
1232 {
1233     char buf[1024];
1234     PyOS_snprintf(
1235         buf, sizeof(buf),
1236         "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1237         "data=0x%zd udata=%p>",
1238         (size_t)(s->e.ident), s->e.filter, s->e.flags,
1239         s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1240     return PyString_FromString(buf);
1241 }
1242 
1243 static int
kqueue_event_init(kqueue_event_Object * self,PyObject * args,PyObject * kwds)1244 kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1245 {
1246     PyObject *pfd;
1247     static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1248                              "data", "udata", NULL};
1249     static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
1250 
1251     EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1252 
1253     if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1254         &pfd, &(self->e.filter), &(self->e.flags),
1255         &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1256         return -1;
1257     }
1258 
1259     if (PyLong_Check(pfd)) {
1260         self->e.ident = PyLong_AsUintptr_t(pfd);
1261     }
1262     else {
1263         self->e.ident = PyObject_AsFileDescriptor(pfd);
1264     }
1265     if (PyErr_Occurred()) {
1266         return -1;
1267     }
1268     return 0;
1269 }
1270 
1271 static PyObject *
kqueue_event_richcompare(kqueue_event_Object * s,kqueue_event_Object * o,int op)1272 kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1273                          int op)
1274 {
1275     Py_intptr_t result = 0;
1276 
1277     if (!kqueue_event_Check(o)) {
1278         if (op == Py_EQ || op == Py_NE) {
1279             PyObject *res = op == Py_EQ ? Py_False : Py_True;
1280             Py_INCREF(res);
1281             return res;
1282         }
1283         PyErr_Format(PyExc_TypeError,
1284             "can't compare %.200s to %.200s",
1285             Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1286         return NULL;
1287     }
1288     if (((result = s->e.ident - o->e.ident) == 0) &&
1289         ((result = s->e.filter - o->e.filter) == 0) &&
1290         ((result = s->e.flags - o->e.flags) == 0) &&
1291         ((result = s->e.fflags - o->e.fflags) == 0) &&
1292         ((result = s->e.data - o->e.data) == 0) &&
1293         ((result = s->e.udata - o->e.udata) == 0)
1294        ) {
1295         result = 0;
1296     }
1297 
1298     switch (op) {
1299         case Py_EQ:
1300         result = (result == 0);
1301         break;
1302         case Py_NE:
1303         result = (result != 0);
1304         break;
1305         case Py_LE:
1306         result = (result <= 0);
1307         break;
1308         case Py_GE:
1309         result = (result >= 0);
1310         break;
1311         case Py_LT:
1312         result = (result < 0);
1313         break;
1314         case Py_GT:
1315         result = (result > 0);
1316         break;
1317     }
1318     return PyBool_FromLong((long)result);
1319 }
1320 
1321 static PyTypeObject kqueue_event_Type = {
1322     PyVarObject_HEAD_INIT(NULL, 0)
1323     "select.kevent",                                    /* tp_name */
1324     sizeof(kqueue_event_Object),                        /* tp_basicsize */
1325     0,                                                  /* tp_itemsize */
1326     0,                                                  /* tp_dealloc */
1327     0,                                                  /* tp_print */
1328     0,                                                  /* tp_getattr */
1329     0,                                                  /* tp_setattr */
1330     0,                                                  /* tp_compare */
1331     (reprfunc)kqueue_event_repr,                        /* tp_repr */
1332     0,                                                  /* tp_as_number */
1333     0,                                                  /* tp_as_sequence */
1334     0,                                                  /* tp_as_mapping */
1335     0,                                                  /* tp_hash */
1336     0,                                                  /* tp_call */
1337     0,                                                  /* tp_str */
1338     0,                                                  /* tp_getattro */
1339     0,                                                  /* tp_setattro */
1340     0,                                                  /* tp_as_buffer */
1341     Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
1342     kqueue_event_doc,                                   /* tp_doc */
1343     0,                                                  /* tp_traverse */
1344     0,                                                  /* tp_clear */
1345     (richcmpfunc)kqueue_event_richcompare,              /* tp_richcompare */
1346     0,                                                  /* tp_weaklistoffset */
1347     0,                                                  /* tp_iter */
1348     0,                                                  /* tp_iternext */
1349     0,                                                  /* tp_methods */
1350     kqueue_event_members,                               /* tp_members */
1351     0,                                                  /* tp_getset */
1352     0,                                                  /* tp_base */
1353     0,                                                  /* tp_dict */
1354     0,                                                  /* tp_descr_get */
1355     0,                                                  /* tp_descr_set */
1356     0,                                                  /* tp_dictoffset */
1357     (initproc)kqueue_event_init,                        /* tp_init */
1358     0,                                                  /* tp_alloc */
1359     0,                                                  /* tp_new */
1360     0,                                                  /* tp_free */
1361 };
1362 
1363 static PyObject *
kqueue_queue_err_closed(void)1364 kqueue_queue_err_closed(void)
1365 {
1366     PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1367     return NULL;
1368 }
1369 
1370 static int
kqueue_queue_internal_close(kqueue_queue_Object * self)1371 kqueue_queue_internal_close(kqueue_queue_Object *self)
1372 {
1373     int save_errno = 0;
1374     if (self->kqfd >= 0) {
1375         int kqfd = self->kqfd;
1376         self->kqfd = -1;
1377         Py_BEGIN_ALLOW_THREADS
1378         if (close(kqfd) < 0)
1379             save_errno = errno;
1380         Py_END_ALLOW_THREADS
1381     }
1382     return save_errno;
1383 }
1384 
1385 static PyObject *
newKqueue_Object(PyTypeObject * type,SOCKET fd)1386 newKqueue_Object(PyTypeObject *type, SOCKET fd)
1387 {
1388     kqueue_queue_Object *self;
1389     assert(type != NULL && type->tp_alloc != NULL);
1390     self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1391     if (self == NULL) {
1392         return NULL;
1393     }
1394 
1395     if (fd == -1) {
1396         Py_BEGIN_ALLOW_THREADS
1397         self->kqfd = kqueue();
1398         Py_END_ALLOW_THREADS
1399     }
1400     else {
1401         self->kqfd = fd;
1402     }
1403     if (self->kqfd < 0) {
1404         Py_DECREF(self);
1405         PyErr_SetFromErrno(PyExc_IOError);
1406         return NULL;
1407     }
1408     return (PyObject *)self;
1409 }
1410 
1411 static PyObject *
kqueue_queue_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1412 kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1413 {
1414 
1415     if ((args != NULL && PyObject_Size(args)) ||
1416                     (kwds != NULL && PyObject_Size(kwds))) {
1417         PyErr_SetString(PyExc_ValueError,
1418                         "select.kqueue doesn't accept arguments");
1419         return NULL;
1420     }
1421 
1422     return newKqueue_Object(type, -1);
1423 }
1424 
1425 static void
kqueue_queue_dealloc(kqueue_queue_Object * self)1426 kqueue_queue_dealloc(kqueue_queue_Object *self)
1427 {
1428     kqueue_queue_internal_close(self);
1429     Py_TYPE(self)->tp_free(self);
1430 }
1431 
1432 static PyObject*
kqueue_queue_close(kqueue_queue_Object * self)1433 kqueue_queue_close(kqueue_queue_Object *self)
1434 {
1435     errno = kqueue_queue_internal_close(self);
1436     if (errno < 0) {
1437         PyErr_SetFromErrno(PyExc_IOError);
1438         return NULL;
1439     }
1440     Py_RETURN_NONE;
1441 }
1442 
1443 PyDoc_STRVAR(kqueue_queue_close_doc,
1444 "close() -> None\n\
1445 \n\
1446 Close the kqueue control file descriptor. Further operations on the kqueue\n\
1447 object will raise an exception.");
1448 
1449 static PyObject*
kqueue_queue_get_closed(kqueue_queue_Object * self)1450 kqueue_queue_get_closed(kqueue_queue_Object *self)
1451 {
1452     if (self->kqfd < 0)
1453         Py_RETURN_TRUE;
1454     else
1455         Py_RETURN_FALSE;
1456 }
1457 
1458 static PyObject*
kqueue_queue_fileno(kqueue_queue_Object * self)1459 kqueue_queue_fileno(kqueue_queue_Object *self)
1460 {
1461     if (self->kqfd < 0)
1462         return kqueue_queue_err_closed();
1463     return PyInt_FromLong(self->kqfd);
1464 }
1465 
1466 PyDoc_STRVAR(kqueue_queue_fileno_doc,
1467 "fileno() -> int\n\
1468 \n\
1469 Return the kqueue control file descriptor.");
1470 
1471 static PyObject*
kqueue_queue_fromfd(PyObject * cls,PyObject * args)1472 kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1473 {
1474     SOCKET fd;
1475 
1476     if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1477         return NULL;
1478 
1479     return newKqueue_Object((PyTypeObject*)cls, fd);
1480 }
1481 
1482 PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1483 "fromfd(fd) -> kqueue\n\
1484 \n\
1485 Create a kqueue object from a given control fd.");
1486 
1487 static PyObject *
kqueue_queue_control(kqueue_queue_Object * self,PyObject * args)1488 kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1489 {
1490     int nevents = 0;
1491     int gotevents = 0;
1492     int nchanges = 0;
1493     int i = 0;
1494     PyObject *otimeout = NULL;
1495     PyObject *ch = NULL;
1496     PyObject *it = NULL, *ei = NULL;
1497     PyObject *result = NULL;
1498     struct kevent *evl = NULL;
1499     struct kevent *chl = NULL;
1500     struct timespec timeoutspec;
1501     struct timespec *ptimeoutspec;
1502 
1503     if (self->kqfd < 0)
1504         return kqueue_queue_err_closed();
1505 
1506     if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1507         return NULL;
1508 
1509     if (nevents < 0) {
1510         PyErr_Format(PyExc_ValueError,
1511             "Length of eventlist must be 0 or positive, got %d",
1512             nevents);
1513         return NULL;
1514     }
1515 
1516     if (otimeout == Py_None || otimeout == NULL) {
1517         ptimeoutspec = NULL;
1518     }
1519     else if (PyNumber_Check(otimeout)) {
1520         double timeout;
1521         long seconds;
1522 
1523         timeout = PyFloat_AsDouble(otimeout);
1524         if (timeout == -1 && PyErr_Occurred())
1525             return NULL;
1526         if (timeout > (double)LONG_MAX) {
1527             PyErr_SetString(PyExc_OverflowError,
1528                             "timeout period too long");
1529             return NULL;
1530         }
1531         if (timeout < 0) {
1532             PyErr_SetString(PyExc_ValueError,
1533                             "timeout must be positive or None");
1534             return NULL;
1535         }
1536 
1537         seconds = (long)timeout;
1538         timeout = timeout - (double)seconds;
1539         timeoutspec.tv_sec = seconds;
1540         timeoutspec.tv_nsec = (long)(timeout * 1E9);
1541         ptimeoutspec = &timeoutspec;
1542     }
1543     else {
1544         PyErr_Format(PyExc_TypeError,
1545             "timeout argument must be an number "
1546             "or None, got %.200s",
1547             Py_TYPE(otimeout)->tp_name);
1548         return NULL;
1549     }
1550 
1551     if (ch != NULL && ch != Py_None) {
1552         it = PyObject_GetIter(ch);
1553         if (it == NULL) {
1554             PyErr_SetString(PyExc_TypeError,
1555                             "changelist is not iterable");
1556             return NULL;
1557         }
1558         nchanges = PyObject_Size(ch);
1559         if (nchanges < 0) {
1560             goto error;
1561         }
1562 
1563         chl = PyMem_New(struct kevent, nchanges);
1564         if (chl == NULL) {
1565             PyErr_NoMemory();
1566             goto error;
1567         }
1568         i = 0;
1569         while ((ei = PyIter_Next(it)) != NULL) {
1570             if (!kqueue_event_Check(ei)) {
1571                 Py_DECREF(ei);
1572                 PyErr_SetString(PyExc_TypeError,
1573                     "changelist must be an iterable of "
1574                     "select.kevent objects");
1575                 goto error;
1576             } else {
1577                 chl[i++] = ((kqueue_event_Object *)ei)->e;
1578             }
1579             Py_DECREF(ei);
1580         }
1581     }
1582     Py_CLEAR(it);
1583 
1584     /* event list */
1585     if (nevents) {
1586         evl = PyMem_New(struct kevent, nevents);
1587         if (evl == NULL) {
1588             PyErr_NoMemory();
1589             goto error;
1590         }
1591     }
1592 
1593     Py_BEGIN_ALLOW_THREADS
1594     gotevents = kevent(self->kqfd, chl, nchanges,
1595                        evl, nevents, ptimeoutspec);
1596     Py_END_ALLOW_THREADS
1597 
1598     if (gotevents == -1) {
1599         PyErr_SetFromErrno(PyExc_OSError);
1600         goto error;
1601     }
1602 
1603     result = PyList_New(gotevents);
1604     if (result == NULL) {
1605         goto error;
1606     }
1607 
1608     for (i = 0; i < gotevents; i++) {
1609         kqueue_event_Object *ch;
1610 
1611         ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1612         if (ch == NULL) {
1613             goto error;
1614         }
1615         ch->e = evl[i];
1616         PyList_SET_ITEM(result, i, (PyObject *)ch);
1617     }
1618     PyMem_Free(chl);
1619     PyMem_Free(evl);
1620     return result;
1621 
1622     error:
1623     PyMem_Free(chl);
1624     PyMem_Free(evl);
1625     Py_XDECREF(result);
1626     Py_XDECREF(it);
1627     return NULL;
1628 }
1629 
1630 PyDoc_STRVAR(kqueue_queue_control_doc,
1631 "control(changelist, max_events[, timeout=None]) -> eventlist\n\
1632 \n\
1633 Calls the kernel kevent function.\n\
1634 - changelist must be a list of kevent objects describing the changes\n\
1635   to be made to the kernel's watch list or None.\n\
1636 - max_events lets you specify the maximum number of events that the\n\
1637   kernel will return.\n\
1638 - timeout is the maximum time to wait in seconds, or else None,\n\
1639   to wait forever. timeout accepts floats for smaller timeouts, too.");
1640 
1641 
1642 static PyMethodDef kqueue_queue_methods[] = {
1643     {"fromfd",          (PyCFunction)kqueue_queue_fromfd,
1644      METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1645     {"close",           (PyCFunction)kqueue_queue_close,        METH_NOARGS,
1646      kqueue_queue_close_doc},
1647     {"fileno",          (PyCFunction)kqueue_queue_fileno,       METH_NOARGS,
1648      kqueue_queue_fileno_doc},
1649     {"control",         (PyCFunction)kqueue_queue_control,
1650      METH_VARARGS ,     kqueue_queue_control_doc},
1651     {NULL,      NULL},
1652 };
1653 
1654 static PyGetSetDef kqueue_queue_getsetlist[] = {
1655     {"closed", (getter)kqueue_queue_get_closed, NULL,
1656      "True if the kqueue handler is closed"},
1657     {0},
1658 };
1659 
1660 PyDoc_STRVAR(kqueue_queue_doc,
1661 "Kqueue syscall wrapper.\n\
1662 \n\
1663 For example, to start watching a socket for input:\n\
1664 >>> kq = kqueue()\n\
1665 >>> sock = socket()\n\
1666 >>> sock.connect((host, port))\n\
1667 >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1668 \n\
1669 To wait one second for it to become writeable:\n\
1670 >>> kq.control(None, 1, 1000)\n\
1671 \n\
1672 To stop listening:\n\
1673 >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1674 
1675 static PyTypeObject kqueue_queue_Type = {
1676     PyVarObject_HEAD_INIT(NULL, 0)
1677     "select.kqueue",                                    /* tp_name */
1678     sizeof(kqueue_queue_Object),                        /* tp_basicsize */
1679     0,                                                  /* tp_itemsize */
1680     (destructor)kqueue_queue_dealloc,                   /* tp_dealloc */
1681     0,                                                  /* tp_print */
1682     0,                                                  /* tp_getattr */
1683     0,                                                  /* tp_setattr */
1684     0,                                                  /* tp_compare */
1685     0,                                                  /* tp_repr */
1686     0,                                                  /* tp_as_number */
1687     0,                                                  /* tp_as_sequence */
1688     0,                                                  /* tp_as_mapping */
1689     0,                                                  /* tp_hash */
1690     0,                                                  /* tp_call */
1691     0,                                                  /* tp_str */
1692     0,                                                  /* tp_getattro */
1693     0,                                                  /* tp_setattro */
1694     0,                                                  /* tp_as_buffer */
1695     Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
1696     kqueue_queue_doc,                                   /* tp_doc */
1697     0,                                                  /* tp_traverse */
1698     0,                                                  /* tp_clear */
1699     0,                                                  /* tp_richcompare */
1700     0,                                                  /* tp_weaklistoffset */
1701     0,                                                  /* tp_iter */
1702     0,                                                  /* tp_iternext */
1703     kqueue_queue_methods,                               /* tp_methods */
1704     0,                                                  /* tp_members */
1705     kqueue_queue_getsetlist,                            /* tp_getset */
1706     0,                                                  /* tp_base */
1707     0,                                                  /* tp_dict */
1708     0,                                                  /* tp_descr_get */
1709     0,                                                  /* tp_descr_set */
1710     0,                                                  /* tp_dictoffset */
1711     0,                                                  /* tp_init */
1712     0,                                                  /* tp_alloc */
1713     kqueue_queue_new,                                   /* tp_new */
1714     0,                                                  /* tp_free */
1715 };
1716 
1717 #endif /* HAVE_KQUEUE */
1718 /* ************************************************************************ */
1719 
1720 PyDoc_STRVAR(select_doc,
1721 "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1722 \n\
1723 Wait until one or more file descriptors are ready for some kind of I/O.\n\
1724 The first three arguments are sequences of file descriptors to be waited for:\n\
1725 rlist -- wait until ready for reading\n\
1726 wlist -- wait until ready for writing\n\
1727 xlist -- wait for an ``exceptional condition''\n\
1728 If only one kind of condition is required, pass [] for the other lists.\n\
1729 A file descriptor is either a socket or file object, or a small integer\n\
1730 gotten from a fileno() method call on one of those.\n\
1731 \n\
1732 The optional 4th argument specifies a timeout in seconds; it may be\n\
1733 a floating point number to specify fractions of seconds.  If it is absent\n\
1734 or None, the call will never time out.\n\
1735 \n\
1736 The return value is a tuple of three lists corresponding to the first three\n\
1737 arguments; each contains the subset of the corresponding file descriptors\n\
1738 that are ready.\n\
1739 \n\
1740 *** IMPORTANT NOTICE ***\n\
1741 On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
1742 descriptors can be used.");
1743 
1744 static PyMethodDef select_methods[] = {
1745     {"select",          select_select,  METH_VARARGS,   select_doc},
1746 #ifdef HAVE_POLL
1747     {"poll",            select_poll,    METH_NOARGS,    poll_doc},
1748 #endif /* HAVE_POLL */
1749     {0,         0},     /* sentinel */
1750 };
1751 
1752 PyDoc_STRVAR(module_doc,
1753 "This module supports asynchronous I/O on multiple file descriptors.\n\
1754 \n\
1755 *** IMPORTANT NOTICE ***\n\
1756 On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
1757 
1758 PyMODINIT_FUNC
initselect(void)1759 initselect(void)
1760 {
1761     PyObject *m;
1762     m = Py_InitModule3("select", select_methods, module_doc);
1763     if (m == NULL)
1764         return;
1765 
1766     SelectError = PyErr_NewException("select.error", NULL, NULL);
1767     Py_INCREF(SelectError);
1768     PyModule_AddObject(m, "error", SelectError);
1769 
1770 #ifdef PIPE_BUF
1771 #ifdef HAVE_BROKEN_PIPE_BUF
1772 #undef PIPE_BUF
1773 #define PIPE_BUF 512
1774 #endif
1775     PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
1776 #endif
1777 
1778 #if defined(HAVE_POLL)
1779 #ifdef __APPLE__
1780     if (select_have_broken_poll()) {
1781         if (PyObject_DelAttrString(m, "poll") == -1) {
1782             PyErr_Clear();
1783         }
1784     } else {
1785 #else
1786     {
1787 #endif
1788         Py_TYPE(&poll_Type) = &PyType_Type;
1789         PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1790         PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1791         PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1792         PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1793         PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1794         PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
1795 
1796 #ifdef POLLRDNORM
1797         PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
1798 #endif
1799 #ifdef POLLRDBAND
1800         PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
1801 #endif
1802 #ifdef POLLWRNORM
1803         PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
1804 #endif
1805 #ifdef POLLWRBAND
1806         PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
1807 #endif
1808 #ifdef POLLMSG
1809         PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
1810 #endif
1811     }
1812 #endif /* HAVE_POLL */
1813 
1814 #ifdef HAVE_EPOLL
1815     Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1816     if (PyType_Ready(&pyEpoll_Type) < 0)
1817         return;
1818 
1819     Py_INCREF(&pyEpoll_Type);
1820     PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
1821 
1822     PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1823     PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1824     PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1825     PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1826     PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1827     PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
1828 #ifdef EPOLLONESHOT
1829     /* Kernel 2.6.2+ */
1830     PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
1831 #endif
1832     /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1833     PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1834     PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1835     PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1836     PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1837     PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
1838 #endif /* HAVE_EPOLL */
1839 
1840 #ifdef HAVE_KQUEUE
1841     kqueue_event_Type.tp_new = PyType_GenericNew;
1842     Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1843     if(PyType_Ready(&kqueue_event_Type) < 0)
1844         return;
1845 
1846     Py_INCREF(&kqueue_event_Type);
1847     PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
1848 
1849     Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1850     if(PyType_Ready(&kqueue_queue_Type) < 0)
1851         return;
1852     Py_INCREF(&kqueue_queue_Type);
1853     PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1854 
1855     /* event filters */
1856     PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1857     PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1858     PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1859     PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1860     PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
1861 #ifdef EVFILT_NETDEV
1862     PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
1863 #endif
1864     PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1865     PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
1866 
1867     /* event flags */
1868     PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1869     PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1870     PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1871     PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1872     PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1873     PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
1874 
1875     PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1876     PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
1877 
1878     PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1879     PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
1880 
1881     /* READ WRITE filter flag */
1882     PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
1883 
1884     /* VNODE filter flags  */
1885     PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1886     PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1887     PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1888     PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1889     PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1890     PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1891     PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
1892 
1893     /* PROC filter flags  */
1894     PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1895     PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1896     PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1897     PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1898     PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
1899 
1900     PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1901     PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1902     PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1903 
1904     /* NETDEV filter flags */
1905 #ifdef EVFILT_NETDEV
1906     PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1907     PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1908     PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
1909 #endif
1910 
1911 #endif /* HAVE_KQUEUE */
1912 }
1913