LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - selectmodule.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 436 0.0 %
Date: 2012-12-17 Functions: 0 27 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10