LCOV - code coverage report
Current view: top level - Modules - selectmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 428 511 83.8 %
Date: 2022-07-07 18:19:46 Functions: 34 34 100.0 %

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

Generated by: LCOV version 1.14