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