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 */
37extern 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
60static PyObject *SelectError;
61
62/* list of Python objects and their file descriptor */
63typedef struct {
64    PyObject *obj;                           /* owned reference */
65    SOCKET fd;
66    int sentinel;                            /* -1 == sentinel */
67} pylist;
68
69static void
70reap_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*/
84static int
85seq2set(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 */
148static PyObject *
149set2list(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
194static PyObject *
195select_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
325typedef struct {
326    PyObject_HEAD
327    PyObject *dict;
328    int ufd_uptodate;
329    int ufd_len;
330    struct pollfd *ufds;
331} pollObject;
332
333static 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
339static int
340update_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
364PyDoc_STRVAR(poll_register_doc,
365"register(fd [, eventmask] ) -> None\n\n\
366Register a file descriptor with the polling object.\n\
367fd -- either an integer, or an object with a fileno() method returning an\n\
368      int.\n\
369events -- an optional bitmask describing the type of events to check for");
370
371static PyObject *
372poll_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
407PyDoc_STRVAR(poll_modify_doc,
408"modify(fd, eventmask) -> None\n\n\
409Modify an already registered file descriptor.\n\
410fd -- either an integer, or an object with a fileno() method returning an\n\
411      int.\n\
412events -- an optional bitmask describing the type of events to check for");
413
414static PyObject *
415poll_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
455PyDoc_STRVAR(poll_unregister_doc,
456"unregister(fd) -> None\n\n\
457Remove a file descriptor being tracked by the polling object.");
458
459static PyObject *
460poll_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
488PyDoc_STRVAR(poll_poll_doc,
489"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
490Polls the set of registered file descriptors, returning a list containing \n\
491any descriptors that have events or errors to report.");
492
493static PyObject *
494poll_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
585static 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
597static pollObject *
598newPollObject(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
616static void
617poll_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
625static PyObject *
626poll_getattr(pollObject *self, char *name)
627{
628    return Py_FindMethod(poll_methods, (PyObject *)self, name);
629}
630
631static 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
651PyDoc_STRVAR(poll_doc,
652"Returns a polling object, which supports registering and\n\
653unregistering file descriptors, and then polling them for I/O events.");
654
655static PyObject *
656select_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 */
667static 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
705typedef struct {
706    PyObject_HEAD
707    SOCKET epfd;                        /* epoll control file descriptor */
708} pyEpoll_Object;
709
710static PyTypeObject pyEpoll_Type;
711#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
712
713static PyObject *
714pyepoll_err_closed(void)
715{
716    PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
717    return NULL;
718}
719
720static int
721pyepoll_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
735static PyObject *
736newPyEpoll_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
772static PyObject *
773pyepoll_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
786static void
787pyepoll_dealloc(pyEpoll_Object *self)
788{
789    (void)pyepoll_internal_close(self);
790    Py_TYPE(self)->tp_free(self);
791}
792
793static PyObject*
794pyepoll_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
804PyDoc_STRVAR(pyepoll_close_doc,
805"close() -> None\n\
806\n\
807Close the epoll control file descriptor. Further operations on the epoll\n\
808object will raise an exception.");
809
810static PyObject*
811pyepoll_get_closed(pyEpoll_Object *self)
812{
813    if (self->epfd < 0)
814        Py_RETURN_TRUE;
815    else
816        Py_RETURN_FALSE;
817}
818
819static PyObject*
820pyepoll_fileno(pyEpoll_Object *self)
821{
822    if (self->epfd < 0)
823        return pyepoll_err_closed();
824    return PyInt_FromLong(self->epfd);
825}
826
827PyDoc_STRVAR(pyepoll_fileno_doc,
828"fileno() -> int\n\
829\n\
830Return the epoll control file descriptor.");
831
832static PyObject*
833pyepoll_fromfd(PyObject *cls, PyObject *args)
834{
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
843PyDoc_STRVAR(pyepoll_fromfd_doc,
844"fromfd(fd) -> epoll\n\
845\n\
846Create an epoll object from a given control fd.");
847
848static PyObject *
849pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
850{
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
897static PyObject *
898pyepoll_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
912PyDoc_STRVAR(pyepoll_register_doc,
913"register(fd[, eventmask]) -> None\n\
914\n\
915Registers a new fd or modifies an already registered fd.\n\
916fd is the target file descriptor of the operation.\n\
917events is a bit set composed of the various EPOLL constants; the default\n\
918is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
919\n\
920The epoll interface supports all file descriptors that support poll.");
921
922static PyObject *
923pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
924{
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
937PyDoc_STRVAR(pyepoll_modify_doc,
938"modify(fd, eventmask) -> None\n\
939\n\
940fd is the target file descriptor of the operation\n\
941events is a bit set composed of the various EPOLL constants");
942
943static PyObject *
944pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
945{
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
957PyDoc_STRVAR(pyepoll_unregister_doc,
958"unregister(fd) -> None\n\
959\n\
960fd is the target file descriptor of the operation.");
961
962static PyObject *
963pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
964{
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
1037PyDoc_STRVAR(pyepoll_poll_doc,
1038"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1039\n\
1040Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1041in seconds (as float). -1 makes poll wait indefinitely.\n\
1042Up to maxevents are returned to the caller.");
1043
1044static PyMethodDef pyepoll_methods[] = {
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
1062static PyGetSetDef pyepoll_getsetlist[] = {
1063    {"closed", (getter)pyepoll_get_closed, NULL,
1064     "True if the epoll handler is closed"},
1065    {0},
1066};
1067
1068PyDoc_STRVAR(pyepoll_doc,
1069"select.epoll([sizehint=-1])\n\
1070\n\
1071Returns an epolling object\n\
1072\n\
1073sizehint must be a positive integer or -1 for the default size. The\n\
1074sizehint is used to optimize internal data structures. It doesn't limit\n\
1075the maximum number of monitored events.");
1076
1077static PyTypeObject pyEpoll_Type = {
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
1154PyDoc_STRVAR(kqueue_event_doc,
1155"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
1156\n\
1157This object is the equivalent of the struct kevent for the C API.\n\
1158\n\
1159See the kqueue manpage for more detailed information about the meaning\n\
1160of the arguments.\n\
1161\n\
1162One minor note: while you might hope that udata could store a\n\
1163reference to a python object, it cannot, because it is impossible to\n\
1164keep a proper reference count of the object once it's passed into the\n\
1165kernel. Therefore, I have restricted it to only storing an integer.  I\n\
1166recommend ignoring it and simply using the 'ident' field to key off\n\
1167of. You could also set up a dictionary on the python side to store a\n\
1168udata->object mapping.");
1169
1170typedef struct {
1171    PyObject_HEAD
1172    struct kevent e;
1173} kqueue_event_Object;
1174
1175static PyTypeObject kqueue_event_Type;
1176
1177#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1178
1179typedef struct {
1180    PyObject_HEAD
1181    SOCKET kqfd;                /* kqueue control fd */
1182} kqueue_queue_Object;
1183
1184static 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)
1218static 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
1229static PyObject *
1230
1231kqueue_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
1243static int
1244kqueue_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
1271static PyObject *
1272kqueue_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
1321static 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
1363static PyObject *
1364kqueue_queue_err_closed(void)
1365{
1366    PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1367    return NULL;
1368}
1369
1370static int
1371kqueue_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
1385static PyObject *
1386newKqueue_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
1411static PyObject *
1412kqueue_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
1425static void
1426kqueue_queue_dealloc(kqueue_queue_Object *self)
1427{
1428    kqueue_queue_internal_close(self);
1429    Py_TYPE(self)->tp_free(self);
1430}
1431
1432static PyObject*
1433kqueue_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
1443PyDoc_STRVAR(kqueue_queue_close_doc,
1444"close() -> None\n\
1445\n\
1446Close the kqueue control file descriptor. Further operations on the kqueue\n\
1447object will raise an exception.");
1448
1449static PyObject*
1450kqueue_queue_get_closed(kqueue_queue_Object *self)
1451{
1452    if (self->kqfd < 0)
1453        Py_RETURN_TRUE;
1454    else
1455        Py_RETURN_FALSE;
1456}
1457
1458static PyObject*
1459kqueue_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
1466PyDoc_STRVAR(kqueue_queue_fileno_doc,
1467"fileno() -> int\n\
1468\n\
1469Return the kqueue control file descriptor.");
1470
1471static PyObject*
1472kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1473{
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
1482PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1483"fromfd(fd) -> kqueue\n\
1484\n\
1485Create a kqueue object from a given control fd.");
1486
1487static PyObject *
1488kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1489{
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
1630PyDoc_STRVAR(kqueue_queue_control_doc,
1631"control(changelist, max_events[, timeout=None]) -> eventlist\n\
1632\n\
1633Calls the kernel kevent function.\n\
1634- changelist must be a list of kevent objects describing the changes\n\
1635  to be made to the kernel's watch list or None.\n\
1636- max_events lets you specify the maximum number of events that the\n\
1637  kernel will return.\n\
1638- timeout is the maximum time to wait in seconds, or else None,\n\
1639  to wait forever. timeout accepts floats for smaller timeouts, too.");
1640
1641
1642static PyMethodDef kqueue_queue_methods[] = {
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
1654static PyGetSetDef kqueue_queue_getsetlist[] = {
1655    {"closed", (getter)kqueue_queue_get_closed, NULL,
1656     "True if the kqueue handler is closed"},
1657    {0},
1658};
1659
1660PyDoc_STRVAR(kqueue_queue_doc,
1661"Kqueue syscall wrapper.\n\
1662\n\
1663For example, to start watching a socket for input:\n\
1664>>> kq = kqueue()\n\
1665>>> sock = socket()\n\
1666>>> sock.connect((host, port))\n\
1667>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1668\n\
1669To wait one second for it to become writeable:\n\
1670>>> kq.control(None, 1, 1000)\n\
1671\n\
1672To stop listening:\n\
1673>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1674
1675static PyTypeObject kqueue_queue_Type = {
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
1720PyDoc_STRVAR(select_doc,
1721"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1722\n\
1723Wait until one or more file descriptors are ready for some kind of I/O.\n\
1724The first three arguments are sequences of file descriptors to be waited for:\n\
1725rlist -- wait until ready for reading\n\
1726wlist -- wait until ready for writing\n\
1727xlist -- wait for an ``exceptional condition''\n\
1728If only one kind of condition is required, pass [] for the other lists.\n\
1729A file descriptor is either a socket or file object, or a small integer\n\
1730gotten from a fileno() method call on one of those.\n\
1731\n\
1732The optional 4th argument specifies a timeout in seconds; it may be\n\
1733a floating point number to specify fractions of seconds.  If it is absent\n\
1734or None, the call will never time out.\n\
1735\n\
1736The return value is a tuple of three lists corresponding to the first three\n\
1737arguments; each contains the subset of the corresponding file descriptors\n\
1738that are ready.\n\
1739\n\
1740*** IMPORTANT NOTICE ***\n\
1741On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
1742descriptors can be used.");
1743
1744static 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
1752PyDoc_STRVAR(module_doc,
1753"This module supports asynchronous I/O on multiple file descriptors.\n\
1754\n\
1755*** IMPORTANT NOTICE ***\n\
1756On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
1757
1758PyMODINIT_FUNC
1759initselect(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