LCOV - code coverage report
Current view: | top level - Modules - selectmodule.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 100 | 505 | 19.8 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 11 | 34 | 32.4 %
|  |  | Branches: | 32 | 273 | 11.7 %

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

Generated by: LCOV version 1.14