1d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel/*  @file
2d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  select - Module containing unix select(2) call.
3d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  Under Unix, the file descriptors are small integers.
4d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  Under Win32, select only exists for sockets, and sockets may
5d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  have any value except INVALID_SOCKET.
6d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
7d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  >= 0.
8d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel
9d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
10d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
11d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  This program and the accompanying materials are licensed and made available under
12d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  the terms and conditions of the BSD License that accompanies this distribution.
13d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  The full text of the license may be found at
14d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  http://opensource.org/licenses/bsd-license.
15d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel
16d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include "Python.h"
213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <structmember.h>
223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef __APPLE__
243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Perform runtime testing for a broken poll on OSX to make it easier
253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * to use the same binary on multiple releases of the OS.
263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     */
273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#undef HAVE_BROKEN_POLL
283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel   64 is too small (too many people have bumped into that limit).
323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel   Here we boost it.
333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel   Users who want even more than the boosted limit should #define
343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel   FD_SETSIZE higher before this; e.g., via compiler /D switch.
353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define FD_SETSIZE 512
383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if defined(HAVE_POLL_H)
413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <poll.h>
423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#elif defined(HAVE_SYS_POLL_H)
433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <sys/poll.h>
443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef __sgi
473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* This is missing from unistd.h */
483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielextern void bzero(void *, int);
493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_SYS_TYPES_H
523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <sys/types.h>
533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if defined(PYOS_OS2) && !defined(PYCC_GCC)
563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <sys/time.h>
573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <utils.h>
583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef MS_WINDOWS
613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#  include <winsock2.h>
623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else
633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#  define SOCKET int
643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#  ifdef __BEOS__
653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#    include <net/socket.h>
663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#  elif defined(__VMS)
673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#    include <socket.h>
683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#  endif
693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *SelectError;
723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* list of Python objects and their file descriptor */
743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieltypedef struct {
753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *obj;                           /* owned reference */
763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SOCKET fd;
773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int sentinel;                            /* -1 == sentinel */
783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel} pylist;
793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielreap_obj(pylist fd2obj[FD_SETSIZE + 1])
823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int i;
843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_CLEAR(fd2obj[i].obj);
863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd2obj[0].sentinel = -1;
883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* returns -1 and sets the Python exception if an error occurred, otherwise
923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel   returns a number >= 0
933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielseq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int i;
983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int max = -1;
993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int index = 0;
1003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject* fast_seq = NULL;
1013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject* o = NULL;
1023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd2obj[0].obj = (PyObject*)0;            /* set list to zero size */
1043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    FD_ZERO(set);
1053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
1073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!fast_seq)
1083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return -1;
1093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++)  {
1113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        SOCKET v;
1123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* any intervening fileno() calls could decr this refcnt */
1143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
1153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return -1;
1163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_INCREF(o);
1183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        v = PyObject_AsFileDescriptor( o );
1193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (v == -1) goto finally;
1203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
121d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#if defined(_MSC_VER) && !defined(UEFI_C_SOURCE)
1223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        max = 0;                             /* not used for Win32 */
1233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else  /* !_MSC_VER */
1243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (!_PyIsSelectable_fd(v)) {
1253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
1263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "filedescriptor out of range in select()");
1273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto finally;
1283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
1293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (v > max)
1303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            max = v;
1313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* _MSC_VER */
1323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        FD_SET(v, set);
1333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* add object and its file descriptor to the list */
1353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (index >= FD_SETSIZE) {
1363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
1373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                          "too many file descriptors in select()");
1383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto finally;
1393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
1403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fd2obj[index].obj = o;
1413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fd2obj[index].fd = v;
1423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fd2obj[index].sentinel = 0;
1433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fd2obj[++index].sentinel = -1;
1443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
1453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(fast_seq);
1463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return max+1;
1473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  finally:
1493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_XDECREF(o);
1503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(fast_seq);
1513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return -1;
1523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
1533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* returns NULL and sets the Python exception if an error occurred */
1553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
1563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielset2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
1573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
1583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int i, j, count=0;
1593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *list, *o;
1603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SOCKET fd;
1613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for (j = 0; fd2obj[j].sentinel >= 0; j++) {
1633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (FD_ISSET(fd2obj[j].fd, set))
1643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            count++;
1653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
1663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    list = PyList_New(count);
1673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!list)
1683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
1693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    i = 0;
1713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for (j = 0; fd2obj[j].sentinel >= 0; j++) {
1723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        fd = fd2obj[j].fd;
1733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (FD_ISSET(fd, set)) {
1743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            o = fd2obj[j].obj;
1753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            fd2obj[j].obj = NULL;
1763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            /* transfer ownership */
1773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (PyList_SetItem(list, i, o) < 0)
1783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                goto finally;
1793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            i++;
1813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
1823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
1833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return list;
1843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  finally:
1853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(list);
1863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return NULL;
1873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
1883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#undef SELECT_USES_HEAP
1903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if FD_SETSIZE > 1024
1913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define SELECT_USES_HEAP
1923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* FD_SETSIZE > 1024 */
1933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
1943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
1953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielselect_select(PyObject *self, PyObject *args)
1963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
1973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef SELECT_USES_HEAP
1983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pylist *rfd2obj, *wfd2obj, *efd2obj;
1993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else  /* !SELECT_USES_HEAP */
2003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* XXX: All this should probably be implemented as follows:
2013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * - find the highest descriptor we're interested in
2023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * - add one
2033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * - that's the size
2043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * See: Stevens, APitUE, $12.5.1
2053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     */
2063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pylist rfd2obj[FD_SETSIZE + 1];
2073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pylist wfd2obj[FD_SETSIZE + 1];
2083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pylist efd2obj[FD_SETSIZE + 1];
2093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* SELECT_USES_HEAP */
2103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *ifdlist, *ofdlist, *efdlist;
2113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *ret = NULL;
2123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *tout = Py_None;
2133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd_set ifdset, ofdset, efdset;
2143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    double timeout;
2153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct timeval tv, *tvp;
2163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    long seconds;
2173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int imax, omax, emax, max;
2183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int n;
2193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* convert arguments */
2213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_UnpackTuple(args, "select", 3, 4,
2223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                          &ifdlist, &ofdlist, &efdlist, &tout))
2233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
2243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (tout == Py_None)
2263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        tvp = (struct timeval *)0;
2273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (!PyNumber_Check(tout)) {
2283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetString(PyExc_TypeError,
2293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "timeout must be a float or None");
2303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
2313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
2333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = PyFloat_AsDouble(tout);
2343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (timeout == -1 && PyErr_Occurred())
2353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
2363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (timeout > (double)LONG_MAX) {
2373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_SetString(PyExc_OverflowError,
2383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                            "timeout period too long");
2393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
2403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
2413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        seconds = (long)timeout;
2423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = timeout - (double)seconds;
2433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        tv.tv_sec = seconds;
2443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        tv.tv_usec = (long)(timeout * 1E6);
2453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        tvp = &tv;
2463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef SELECT_USES_HEAP
2503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Allocate memory for the lists */
2513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
2523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
2533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
2543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
2553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (rfd2obj) PyMem_DEL(rfd2obj);
2563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (wfd2obj) PyMem_DEL(wfd2obj);
2573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (efd2obj) PyMem_DEL(efd2obj);
2583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return PyErr_NoMemory();
2593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* SELECT_USES_HEAP */
2613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Convert sequences to fd_sets, and get maximum fd number
2623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * propagates the Python exception set in seq2set()
2633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     */
2643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    rfd2obj[0].sentinel = -1;
2653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    wfd2obj[0].sentinel = -1;
2663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    efd2obj[0].sentinel = -1;
2673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
2683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto finally;
2693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
2703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto finally;
2713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
2723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto finally;
2733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    max = imax;
2743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (omax > max) max = omax;
2753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (emax > max) max = emax;
2763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_BEGIN_ALLOW_THREADS
2783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    n = select(max, &ifdset, &ofdset, &efdset, tvp);
2793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_END_ALLOW_THREADS
2803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
2813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef MS_WINDOWS
2823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (n == SOCKET_ERROR) {
2833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
2843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else
2863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (n < 0) {
2873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(SelectError);
2883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
2893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
2903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
2913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* any of these three calls can raise an exception.  it's more
2923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel           convenient to test for this after all three calls... but
2933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel           is that acceptable?
2943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        */
2953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ifdlist = set2list(&ifdset, rfd2obj);
2963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ofdlist = set2list(&ofdset, wfd2obj);
2973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        efdlist = set2list(&efdset, efd2obj);
2983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (PyErr_Occurred())
2993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            ret = NULL;
3003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        else
3013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
3023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(ifdlist);
3043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(ofdlist);
3053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(efdlist);
3063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
3073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  finally:
3093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reap_obj(rfd2obj);
3103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reap_obj(wfd2obj);
3113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    reap_obj(efd2obj);
3123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef SELECT_USES_HEAP
3133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_DEL(rfd2obj);
3143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_DEL(wfd2obj);
3153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_DEL(efd2obj);
3163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* SELECT_USES_HEAP */
3173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return ret;
3183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
3193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
3213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/*
3223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * poll() support
3233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel */
3243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieltypedef struct {
3263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject_HEAD
3273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *dict;
3283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int ufd_uptodate;
3293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int ufd_len;
3303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct pollfd *ufds;
3313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int poll_running;
3323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel} pollObject;
3333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject poll_Type;
3353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* Update the malloc'ed array of pollfds to match the dictionary
3373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel   contained within a pollObject.  Return 1 on success, 0 on an error.
3383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*/
3393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
3413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielupdate_ufd_array(pollObject *self)
3423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
3433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_ssize_t i, pos;
3443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *key, *value;
3453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct pollfd *old_ufds = self->ufds;
3463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufd_len = PyDict_Size(self->dict);
3483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
3493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->ufds == NULL) {
3503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->ufds = old_ufds;
3513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_NoMemory();
3523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 0;
3533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
3543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    i = pos = 0;
3563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    while (PyDict_Next(self->dict, &pos, &key, &value)) {
3573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        assert(i < self->ufd_len);
3583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* Never overflow */
3593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->ufds[i].fd = (int)PyInt_AsLong(key);
3603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->ufds[i].events = (short)(unsigned short)PyInt_AsLong(value);
3613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        i++;
3623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
3633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    assert(i == self->ufd_len);
3643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufd_uptodate = 1;
3653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return 1;
3663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
3673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
3693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielushort_converter(PyObject *obj, void *ptr)
3703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
3713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    unsigned long uval;
3723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    uval = PyLong_AsUnsignedLong(obj);
3743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (uval == (unsigned long)-1 && PyErr_Occurred())
3753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 0;
3763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (uval > USHRT_MAX) {
3773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetString(PyExc_OverflowError,
3783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "Python int too large for C unsigned short");
3793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 0;
3803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
3813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
3833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return 1;
3843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
3853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(poll_register_doc,
3873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"register(fd [, eventmask] ) -> None\n\n\
3883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielRegister a file descriptor with the polling object.\n\
3893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielfd -- either an integer, or an object with a fileno() method returning an\n\
3903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      int.\n\
3913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielevents -- an optional bitmask describing the type of events to check for");
3923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
3933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
3943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpoll_register(pollObject *self, PyObject *args)
3953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
3963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *o, *key, *value;
3973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int fd;
3983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    unsigned short events = POLLIN | POLLPRI | POLLOUT;
3993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int err;
4003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
4023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd = PyObject_AsFileDescriptor(o);
4053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (fd == -1) return NULL;
4063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Add entry to the internal dictionary: the key is the
4083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel       file descriptor, and the value is the event mask. */
4093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    key = PyInt_FromLong(fd);
4103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (key == NULL)
4113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    value = PyInt_FromLong(events);
4133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (value == NULL) {
4143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(key);
4153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
4173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    err = PyDict_SetItem(self->dict, key, value);
4183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(key);
4193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(value);
4203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (err < 0)
4213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufd_uptodate = 0;
4243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(Py_None);
4263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return Py_None;
4273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
4283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(poll_modify_doc,
4303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"modify(fd, eventmask) -> None\n\n\
4313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielModify an already registered file descriptor.\n\
4323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielfd -- either an integer, or an object with a fileno() method returning an\n\
4333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel      int.\n\
4343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielevents -- an optional bitmask describing the type of events to check for");
4353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
4373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpoll_modify(pollObject *self, PyObject *args)
4383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
4393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *o, *key, *value;
4403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int fd;
4413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    unsigned short events;
4423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int err;
4433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
4453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd = PyObject_AsFileDescriptor(o);
4483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (fd == -1) return NULL;
4493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Modify registered fd */
4513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    key = PyInt_FromLong(fd);
4523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (key == NULL)
4533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (PyDict_GetItem(self->dict, key) == NULL) {
4553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        errno = ENOENT;
4563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
4573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
4593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    value = PyInt_FromLong(events);
4603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (value == NULL) {
4613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(key);
4623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
4643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    err = PyDict_SetItem(self->dict, key, value);
4653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(key);
4663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(value);
4673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (err < 0)
4683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufd_uptodate = 0;
4713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(Py_None);
4733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return Py_None;
4743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
4753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(poll_unregister_doc,
4783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"unregister(fd) -> None\n\n\
4793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielRemove a file descriptor being tracked by the polling object.");
4803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
4823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpoll_unregister(pollObject *self, PyObject *o)
4833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
4843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *key;
4853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int fd;
4863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd = PyObject_AsFileDescriptor( o );
4883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (fd == -1)
4893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Check whether the fd is already in the array */
4923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    key = PyInt_FromLong(fd);
4933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (key == NULL)
4943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
4953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
4963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (PyDict_DelItem(self->dict, key) == -1) {
4973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(key);
4983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* This will simply raise the KeyError set by PyDict_DelItem
4993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel           if the file descriptor isn't registered. */
5003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
5013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(key);
5043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufd_uptodate = 0;
5053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(Py_None);
5073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return Py_None;
5083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
5093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(poll_poll_doc,
5113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
5123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPolls the set of registered file descriptors, returning a list containing \n\
5133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielany descriptors that have events or errors to report.");
5143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
5163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpoll_poll(pollObject *self, PyObject *args)
5173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
5183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *result_list = NULL, *tout = NULL;
5193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int timeout = 0, poll_result, i, j;
5203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *value = NULL, *num = NULL;
5213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
5233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
5243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Check values for timeout */
5273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (tout == NULL || tout == Py_None)
5283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = -1;
5293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (!PyNumber_Check(tout)) {
5303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetString(PyExc_TypeError,
5313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "timeout must be an integer or None");
5323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
5333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
5353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        tout = PyNumber_Int(tout);
5363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (!tout)
5373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
5383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = _PyInt_AsInt(tout);
5393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(tout);
5403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (timeout == -1 && PyErr_Occurred())
5413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
5423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Avoid concurrent poll() invocation, issue 8865 */
5453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->poll_running) {
5463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetString(PyExc_RuntimeError,
5473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "concurrent poll() invocation");
5483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
5493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Ensure the ufd array is up to date */
5523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!self->ufd_uptodate)
5533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (update_ufd_array(self) == 0)
5543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
5553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->poll_running = 1;
5573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* call poll() */
5593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_BEGIN_ALLOW_THREADS
5603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    poll_result = poll(self->ufds, self->ufd_len, timeout);
5613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_END_ALLOW_THREADS
5623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->poll_running = 0;
5643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (poll_result < 0) {
5663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(SelectError);
5673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
5683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
5693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* build the result list */
5713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    result_list = PyList_New(poll_result);
5733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!result_list)
5743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
5753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
5763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        for (i = 0, j = 0; j < poll_result; j++) {
5773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            /* skip to the next fired descriptor */
5783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            while (!self->ufds[i].revents) {
5793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                i++;
5803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
5813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            /* if we hit a NULL return, set value to NULL
5823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel               and break out of loop; code at end will
5833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel               clean up result_list */
5843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            value = PyTuple_New(2);
5853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (value == NULL)
5863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                goto error;
5873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            num = PyInt_FromLong(self->ufds[i].fd);
5883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (num == NULL) {
5893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                Py_DECREF(value);
5903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                goto error;
5913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
5923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyTuple_SET_ITEM(value, 0, num);
5933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
5943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            /* The &0xffff is a workaround for AIX.  'revents'
5953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel               is a 16-bit short, and IBM assigned POLLNVAL
5963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel               to be 0x8000, so the conversion to int results
5973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel               in a negative number. See SF bug #923315. */
5983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
5993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (num == NULL) {
6003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                Py_DECREF(value);
6013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                goto error;
6023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
6033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyTuple_SET_ITEM(value, 1, num);
6043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if ((PyList_SetItem(result_list, j, value)) == -1) {
6053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                Py_DECREF(value);
6063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                goto error;
6073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
6083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            i++;
6093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
6103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
6113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return result_list;
6123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  error:
6143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_DECREF(result_list);
6153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return NULL;
6163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyMethodDef poll_methods[] = {
6193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"register",        (PyCFunction)poll_register,
6203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS,  poll_register_doc},
6213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"modify",          (PyCFunction)poll_modify,
6223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS,  poll_modify_doc},
6233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"unregister",      (PyCFunction)poll_unregister,
6243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_O,        poll_unregister_doc},
6253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"poll",            (PyCFunction)poll_poll,
6263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS,  poll_poll_doc},
6273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {NULL,              NULL}           /* sentinel */
6283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
6293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic pollObject *
6313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielnewPollObject(void)
6323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pollObject *self;
6343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self = PyObject_New(pollObject, &poll_Type);
6353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self == NULL)
6363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
6373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* ufd_uptodate is a Boolean, denoting whether the
6383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel       array pointed to by ufds matches the contents of the dictionary. */
6393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufd_uptodate = 0;
6403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->ufds = NULL;
6413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->poll_running = 0;
6423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self->dict = PyDict_New();
6433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->dict == NULL) {
6443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(self);
6453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
6463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
6473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return self;
6483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
6513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpoll_dealloc(pollObject *self)
6523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->ufds != NULL)
6543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyMem_DEL(self->ufds);
6553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_XDECREF(self->dict);
6563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject_Del(self);
6573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
6603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpoll_getattr(pollObject *self, char *name)
6613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return Py_FindMethod(poll_methods, (PyObject *)self, name);
6633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject poll_Type = {
6663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* The ob_type field must be initialized in the module init function
6673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     * to be portable to Windows without using C++. */
6683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
6693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    "select.poll",              /*tp_name*/
6703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    sizeof(pollObject),         /*tp_basicsize*/
6713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_itemsize*/
6723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* methods */
6733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (destructor)poll_dealloc, /*tp_dealloc*/
6743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_print*/
6753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (getattrfunc)poll_getattr, /*tp_getattr*/
6763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                      /*tp_setattr*/
6773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_compare*/
6783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_repr*/
6793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_as_number*/
6803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_as_sequence*/
6813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_as_mapping*/
6823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                          /*tp_hash*/
6833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
6843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(poll_doc,
6863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"Returns a polling object, which supports registering and\n\
6873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielunregistering file descriptors, and then polling them for I/O events.");
6883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
6903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielselect_poll(PyObject *self, PyObject *unused)
6913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
6923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return (PyObject *)newPollObject();
6933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
6943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
6953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef __APPLE__
6963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/*
6973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * On some systems poll() sets errno on invalid file descriptors. We test
6983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * for this at runtime because this bug may be fixed or introduced between
6993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * OS releases.
7003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel */
7013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int select_have_broken_poll(void)
7023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
7033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int poll_test;
7043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int filedes[2];
7053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
7073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Create a file descriptor to make invalid */
7093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (pipe(filedes) < 0) {
7103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 1;
7113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    poll_struct.fd = filedes[0];
7133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    close(filedes[0]);
7143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    close(filedes[1]);
7153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    poll_test = poll(&poll_struct, 1, 0);
7163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (poll_test < 0) {
7173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 1;
7183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
7193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return 1;
7203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return 0;
7223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
7233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* __APPLE__ */
7243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_POLL */
7263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_EPOLL
7283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* **************************************************************************
7293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *                      epoll interface for Linux 2.6
7303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *
7313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * Written by Christian Heimes
7323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * Inspired by Twisted's _epoll.pyx and select.poll()
7333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel */
7343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_SYS_EPOLL_H
7363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <sys/epoll.h>
7373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
7383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieltypedef struct {
7403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject_HEAD
7413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SOCKET epfd;                        /* epoll control file descriptor */
7423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel} pyEpoll_Object;
7433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject pyEpoll_Type;
7453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
7463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
7483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_err_closed(void)
7493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
7503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
7513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return NULL;
7523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
7533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
7553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_internal_close(pyEpoll_Object *self)
7563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
7573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int save_errno = 0;
7583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->epfd >= 0) {
7593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        int epfd = self->epfd;
7603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->epfd = -1;
7613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_BEGIN_ALLOW_THREADS
7623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (close(epfd) < 0)
7633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            save_errno = errno;
7643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_END_ALLOW_THREADS
7653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return save_errno;
7673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
7683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
7703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielnewPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
7713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
7723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pyEpoll_Object *self;
7733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (sizehint == -1) {
7753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        sizehint = FD_SETSIZE-1;
7763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (sizehint < 1) {
7783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_Format(PyExc_ValueError,
7793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                     "sizehint must be greater zero, got %d",
7803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                     sizehint);
7813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
7823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    assert(type != NULL && type->tp_alloc != NULL);
7853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self = (pyEpoll_Object *) type->tp_alloc(type, 0);
7863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self == NULL)
7873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
7883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
7893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (fd == -1) {
7903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_BEGIN_ALLOW_THREADS
7913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->epfd = epoll_create(sizehint);
7923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_END_ALLOW_THREADS
7933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
7953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->epfd = fd;
7963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
7973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->epfd < 0) {
7983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(self);
7993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
8003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
8013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
8023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return (PyObject *)self;
8033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
8073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
8083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int sizehint = -1;
8103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *kwlist[] = {"sizehint", NULL};
8113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
8133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                                     &sizehint))
8143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
8153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return newPyEpoll_Object(type, sizehint, -1);
8173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
8213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_dealloc(pyEpoll_Object *self)
8223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (void)pyepoll_internal_close(self);
8243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TYPE(self)->tp_free(self);
8253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
8283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_close(pyEpoll_Object *self)
8293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    errno = pyepoll_internal_close(self);
8313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (errno < 0) {
8323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
8333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
8343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
8353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_RETURN_NONE;
8363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_close_doc,
8393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"close() -> None\n\
8403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
8413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielClose the epoll control file descriptor. Further operations on the epoll\n\
8423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielobject will raise an exception.");
8433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
8453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_get_closed(pyEpoll_Object *self)
8463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->epfd < 0)
8483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_RETURN_TRUE;
8493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else
8503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_RETURN_FALSE;
8513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
8543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_fileno(pyEpoll_Object *self)
8553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->epfd < 0)
8573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return pyepoll_err_closed();
8583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return PyInt_FromLong(self->epfd);
8593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_fileno_doc,
8623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"fileno() -> int\n\
8633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
8643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielReturn the epoll control file descriptor.");
8653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
8673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_fromfd(PyObject *cls, PyObject *args)
8683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SOCKET fd;
8703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
8723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
8733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
8753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
8763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_fromfd_doc,
8783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"fromfd(fd) -> epoll\n\
8793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
8803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielCreate an epoll object from a given control fd.");
8813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
8833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
8843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
8853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct epoll_event ev;
8863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int result;
8873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int fd;
8883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (epfd < 0)
8903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return pyepoll_err_closed();
8913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    fd = PyObject_AsFileDescriptor(pfd);
8933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (fd == -1) {
8943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
8953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
8963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
8973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    switch(op) {
8983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case EPOLL_CTL_ADD:
8993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case EPOLL_CTL_MOD:
9003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ev.events = events;
9013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ev.data.fd = fd;
9023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_BEGIN_ALLOW_THREADS
9033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = epoll_ctl(epfd, op, fd, &ev);
9043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_END_ALLOW_THREADS
9053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
9063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case EPOLL_CTL_DEL:
9073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
9083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel         * operation required a non-NULL pointer in event, even
9093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel         * though this argument is ignored. */
9103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_BEGIN_ALLOW_THREADS
9113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = epoll_ctl(epfd, op, fd, &ev);
9123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (errno == EBADF) {
9133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            /* fd already closed */
9143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            result = 0;
9153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            errno = 0;
9163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
9173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_END_ALLOW_THREADS
9183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
9193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        default:
9203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = -1;
9213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        errno = EINVAL;
9223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
9233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (result < 0) {
9253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
9263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
9273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
9283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_RETURN_NONE;
9293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
9303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
9323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
9333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
9343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *pfd;
9353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
9363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *kwlist[] = {"fd", "eventmask", NULL};
9373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
9393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                                     &pfd, &events)) {
9403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
9413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
9423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
9443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
9453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_register_doc,
9473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"register(fd[, eventmask]) -> None\n\
9483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
9493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielRegisters a new fd or raises an IOError if the fd is already registered.\n\
9503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielfd is the target file descriptor of the operation.\n\
9513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielevents is a bit set composed of the various EPOLL constants; the default\n\
9523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielis EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
9533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
9543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielThe epoll interface supports all file descriptors that support poll.");
9553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
9573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
9583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
9593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *pfd;
9603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    unsigned int events;
9613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *kwlist[] = {"fd", "eventmask", NULL};
9623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
9643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                                     &pfd, &events)) {
9653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
9663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
9673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
9693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
9703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_modify_doc,
9723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"modify(fd, eventmask) -> None\n\
9733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
9743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielfd is the target file descriptor of the operation\n\
9753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielevents is a bit set composed of the various EPOLL constants");
9763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
9783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
9793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
9803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *pfd;
9813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *kwlist[] = {"fd", NULL};
9823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
9843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                                     &pfd)) {
9853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
9863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
9873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
9893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
9903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_unregister_doc,
9923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"unregister(fd) -> None\n\
9933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
9943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielfd is the target file descriptor of the operation.");
9953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
9963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
9973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielpyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
9983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
9993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    double dtimeout = -1.;
10003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int timeout;
10013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int maxevents = -1;
10023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int nfds, i;
10033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *elist = NULL, *etuple = NULL;
10043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct epoll_event *evs = NULL;
10053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *kwlist[] = {"timeout", "maxevents", NULL};
10063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->epfd < 0)
10083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return pyepoll_err_closed();
10093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
10113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                                     &dtimeout, &maxevents)) {
10123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
10133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (dtimeout < 0) {
10163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = -1;
10173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (dtimeout * 1000.0 > INT_MAX) {
10193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetString(PyExc_OverflowError,
10203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "timeout is too large");
10213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
10223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
10243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = (int)(dtimeout * 1000.0);
10253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (maxevents == -1) {
10283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        maxevents = FD_SETSIZE-1;
10293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (maxevents < 1) {
10313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_Format(PyExc_ValueError,
10323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                     "maxevents must be greater than 0, got %d",
10333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                     maxevents);
10343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
10353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    evs = PyMem_New(struct epoll_event, maxevents);
10383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (evs == NULL) {
10393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(self);
10403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_NoMemory();
10413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
10423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_BEGIN_ALLOW_THREADS
10453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
10463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_END_ALLOW_THREADS
10473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (nfds < 0) {
10483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
10493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto error;
10503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    elist = PyList_New(nfds);
10533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (elist == NULL) {
10543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto error;
10553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for (i = 0; i < nfds; i++) {
10583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
10593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (etuple == NULL) {
10603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            Py_CLEAR(elist);
10613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto error;
10623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
10633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyList_SET_ITEM(elist, i, etuple);
10643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
10653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    error:
10673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_Free(evs);
10683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return elist;
10693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
10703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_poll_doc,
10723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
10733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
10743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielWait for events on the epoll file descriptor for a maximum time of timeout\n\
10753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielin seconds (as float). -1 makes poll wait indefinitely.\n\
10763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielUp to maxevents are returned to the caller.");
10773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyMethodDef pyepoll_methods[] = {
10793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"fromfd",          (PyCFunction)pyepoll_fromfd,
10803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
10813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"close",           (PyCFunction)pyepoll_close,     METH_NOARGS,
10823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     pyepoll_close_doc},
10833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"fileno",          (PyCFunction)pyepoll_fileno,    METH_NOARGS,
10843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     pyepoll_fileno_doc},
10853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"modify",          (PyCFunction)pyepoll_modify,
10863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS | METH_KEYWORDS,      pyepoll_modify_doc},
10873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"register",        (PyCFunction)pyepoll_register,
10883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS | METH_KEYWORDS,      pyepoll_register_doc},
10893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"unregister",      (PyCFunction)pyepoll_unregister,
10903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS | METH_KEYWORDS,      pyepoll_unregister_doc},
10913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"poll",            (PyCFunction)pyepoll_poll,
10923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS | METH_KEYWORDS,      pyepoll_poll_doc},
10933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {NULL,      NULL},
10943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
10953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
10963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyGetSetDef pyepoll_getsetlist[] = {
10973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"closed", (getter)pyepoll_get_closed, NULL,
10983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     "True if the epoll handler is closed"},
10993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {0},
11003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
11013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
11023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(pyepoll_doc,
11033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"select.epoll([sizehint=-1])\n\
11043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
11053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielReturns an epolling object\n\
11063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
11073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielsizehint must be a positive integer or -1 for the default size. The\n\
11083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielsizehint is used to optimize internal data structures. It doesn't limit\n\
11093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielthe maximum number of monitored events.");
11103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
11113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject pyEpoll_Type = {
11123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
11133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    "select.epoll",                                     /* tp_name */
11143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    sizeof(pyEpoll_Object),                             /* tp_basicsize */
11153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_itemsize */
11163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (destructor)pyepoll_dealloc,                        /* tp_dealloc */
11173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_print */
11183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_getattr */
11193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_setattr */
11203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_compare */
11213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_repr */
11223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_number */
11233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_sequence */
11243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_mapping */
11253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_hash */
11263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_call */
11273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_str */
11283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject_GenericGetAttr,                            /* tp_getattro */
11293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_setattro */
11303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_buffer */
11313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
11323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pyepoll_doc,                                        /* tp_doc */
11333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_traverse */
11343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_clear */
11353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_richcompare */
11363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_weaklistoffset */
11373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_iter */
11383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_iternext */
11393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pyepoll_methods,                                    /* tp_methods */
11403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_members */
11413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pyepoll_getsetlist,                                 /* tp_getset */
11423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_base */
11433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dict */
11443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_descr_get */
11453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_descr_set */
11463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dictoffset */
11473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_init */
11483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_alloc */
11493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    pyepoll_new,                                        /* tp_new */
11503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_free */
11513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
11523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
11533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_EPOLL */
11543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
11553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_KQUEUE
11563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* **************************************************************************
11573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *                      kqueue interface for BSD
11583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *
11593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
11603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * All rights reserved.
11613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *
11623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * Redistribution and use in source and binary forms, with or without
11633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * modification, are permitted provided that the following conditions
11643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * are met:
11653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * 1. Redistributions of source code must retain the above copyright
11663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *    notice, this list of conditions and the following disclaimer.
11673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * 2. Redistributions in binary form must reproduce the above copyright
11683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *    notice, this list of conditions and the following disclaimer in the
11693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *    documentation and/or other materials provided with the distribution.
11703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel *
11713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
11723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
11733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
11753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
11773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
11783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
11793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
11803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
11813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * SUCH DAMAGE.
11823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel */
11833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
11843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_SYS_EVENT_H
11853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#include <sys/event.h>
11863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
11873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
11883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(kqueue_event_doc,
11893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
11903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
11913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielThis object is the equivalent of the struct kevent for the C API.\n\
11923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
11933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielSee the kqueue manpage for more detailed information about the meaning\n\
11943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielof the arguments.\n\
11953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
11963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielOne minor note: while you might hope that udata could store a\n\
11973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielreference to a python object, it cannot, because it is impossible to\n\
11983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkeep a proper reference count of the object once it's passed into the\n\
11993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkernel. Therefore, I have restricted it to only storing an integer.  I\n\
12003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielrecommend ignoring it and simply using the 'ident' field to key off\n\
12013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielof. You could also set up a dictionary on the python side to store a\n\
12023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieludata->object mapping.");
12033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieltypedef struct {
12053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject_HEAD
12063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct kevent e;
12073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel} kqueue_event_Object;
12083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject kqueue_event_Type;
12103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
12123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieltypedef struct {
12143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject_HEAD
12153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SOCKET kqfd;                /* kqueue control fd */
12163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel} kqueue_queue_Object;
12173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject kqueue_queue_Type;
12193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
12213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
12233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   error uintptr_t does not match void *!
12243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
12253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define T_UINTPTRT         T_ULONGLONG
12263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define T_INTPTRT          T_LONGLONG
12273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
12283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define UINTPTRT_FMT_UNIT  "K"
12293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define INTPTRT_FMT_UNIT   "L"
12303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
12313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define T_UINTPTRT         T_ULONG
12323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define T_INTPTRT          T_LONG
12333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
12343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define UINTPTRT_FMT_UNIT  "k"
12353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define INTPTRT_FMT_UNIT   "l"
12363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
12373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define T_UINTPTRT         T_UINT
12383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define T_INTPTRT          T_INT
12393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
12403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define UINTPTRT_FMT_UNIT  "I"
12413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define INTPTRT_FMT_UNIT   "i"
12423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else
12433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   error uintptr_t does not match int, long, or long long!
12443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
12453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/*
12473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * kevent is not standard and its members vary across BSDs.
12483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel */
12493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if !defined(__OpenBSD__)
1250d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define IDENT_TYPE T_UINTPTRT
1251d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define IDENT_CAST Py_intptr_t
1252d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define DATA_TYPE  T_INTPTRT
12533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1254d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define IDENT_AsType PyLong_AsUintptr_t
12553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else
1256d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define IDENT_TYPE T_UINT
1257d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define IDENT_CAST int
1258d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define DATA_TYPE  T_INT
12593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#   define DATA_FMT_UNIT "i"
1260d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel#   define IDENT_AsType PyLong_AsUnsignedLong
12613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
12623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* Unfortunately, we can't store python objects in udata, because
12643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * kevents in the kernel can be removed without warning, which would
12653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel * forever lose the refcount on the object stored with it.
12663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel */
12673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
12693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic struct PyMemberDef kqueue_event_members[] = {
12703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"ident",           IDENT_TYPE,     KQ_OFF(e.ident)},
12713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"filter",          T_SHORT,        KQ_OFF(e.filter)},
12723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"flags",           T_USHORT,       KQ_OFF(e.flags)},
12733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"fflags",          T_UINT,         KQ_OFF(e.fflags)},
12743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"data",            DATA_TYPE,      KQ_OFF(e.data)},
12753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"udata",           T_UINTPTRT,     KQ_OFF(e.udata)},
12763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {NULL} /* Sentinel */
12773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
12783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#undef KQ_OFF
12793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
12813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_event_repr(kqueue_event_Object *s)
12833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
12843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    char buf[1024];
12853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyOS_snprintf(
12863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        buf, sizeof(buf),
12873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
12883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        "data=0x%zd udata=%p>",
12893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        (size_t)(s->e.ident), s->e.filter, s->e.flags,
12903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
12913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return PyString_FromString(buf);
12923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
12933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
12943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
12953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
12963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
12973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *pfd;
12983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *kwlist[] = {"ident", "filter", "flags", "fflags",
12993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                             "data", "udata", NULL};
13003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
13013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
13033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
13053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        &pfd, &(self->e.filter), &(self->e.flags),
13063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
13073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return -1;
13083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (PyLong_Check(pfd)
13113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if IDENT_TYPE == T_UINT
1312d11973f1cae1d8e25017b09734fbf419342b192aDaryl McDaniel  && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
13133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
13143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    ) {
13153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->e.ident = IDENT_AsType(pfd);
13163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
13183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->e.ident = PyObject_AsFileDescriptor(pfd);
13193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (PyErr_Occurred()) {
13213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return -1;
13223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return 0;
13243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
13253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
13273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
13283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                         int op)
13293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
13303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_intptr_t result = 0;
13313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!kqueue_event_Check(o)) {
13333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (op == Py_EQ || op == Py_NE) {
13343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyObject *res = op == Py_EQ ? Py_False : Py_True;
13353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            Py_INCREF(res);
13363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return res;
13373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
13383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_Format(PyExc_TypeError,
13393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            "can't compare %.200s to %.200s",
13403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
13413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
13423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
13443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ((result = s->e.filter - o->e.filter) == 0) &&
13453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ((result = s->e.flags - o->e.flags) == 0) &&
13463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
13473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ((result = s->e.data - o->e.data) == 0) &&
13483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ((result = s->e.udata - o->e.udata) == 0)
13493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel       ) {
13503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = 0;
13513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    switch (op) {
13543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case Py_EQ:
13553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = (result == 0);
13563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
13573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case Py_NE:
13583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = (result != 0);
13593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
13603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case Py_LE:
13613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = (result <= 0);
13623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
13633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case Py_GE:
13643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = (result >= 0);
13653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
13663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case Py_LT:
13673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = (result < 0);
13683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
13693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        case Py_GT:
13703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        result = (result > 0);
13713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        break;
13723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
13733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return PyBool_FromLong((long)result);
13743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
13753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
13763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject kqueue_event_Type = {
13773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
13783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    "select.kevent",                                    /* tp_name */
13793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    sizeof(kqueue_event_Object),                        /* tp_basicsize */
13803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_itemsize */
13813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dealloc */
13823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_print */
13833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_getattr */
13843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_setattr */
13853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_compare */
13863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (reprfunc)kqueue_event_repr,                        /* tp_repr */
13873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_number */
13883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_sequence */
13893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_mapping */
13903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_hash */
13913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_call */
13923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_str */
13933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_getattro */
13943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_setattro */
13953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_buffer */
13963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
13973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_event_doc,                                   /* tp_doc */
13983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_traverse */
13993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_clear */
14003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (richcmpfunc)kqueue_event_richcompare,              /* tp_richcompare */
14013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_weaklistoffset */
14023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_iter */
14033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_iternext */
14043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_methods */
14053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_event_members,                               /* tp_members */
14063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_getset */
14073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_base */
14083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dict */
14093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_descr_get */
14103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_descr_set */
14113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dictoffset */
14123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (initproc)kqueue_event_init,                        /* tp_init */
14133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_alloc */
14143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_new */
14153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_free */
14163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
14173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
14193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_err_closed(void)
14203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
14213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
14223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return NULL;
14233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
14243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic int
14263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_internal_close(kqueue_queue_Object *self)
14273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
14283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int save_errno = 0;
14293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->kqfd >= 0) {
14303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        int kqfd = self->kqfd;
14313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->kqfd = -1;
14323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_BEGIN_ALLOW_THREADS
14333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (close(kqfd) < 0)
14343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            save_errno = errno;
14353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_END_ALLOW_THREADS
14363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return save_errno;
14383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
14393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
14413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielnewKqueue_Object(PyTypeObject *type, SOCKET fd)
14423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
14433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_queue_Object *self;
14443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    assert(type != NULL && type->tp_alloc != NULL);
14453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
14463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self == NULL) {
14473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
14483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (fd == -1) {
14513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_BEGIN_ALLOW_THREADS
14523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->kqfd = kqueue();
14533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_END_ALLOW_THREADS
14543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
14563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        self->kqfd = fd;
14573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->kqfd < 0) {
14593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_DECREF(self);
14603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
14613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
14623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return (PyObject *)self;
14643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
14653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
14673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
14693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if ((args != NULL && PyObject_Size(args)) ||
14713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                    (kwds != NULL && PyObject_Size(kwds))) {
14723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
14733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                        "select.kqueue doesn't accept arguments");
14743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
14753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return newKqueue_Object(type, -1);
14783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
14793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic void
14813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_dealloc(kqueue_queue_Object *self)
14823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
14833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_queue_internal_close(self);
14843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TYPE(self)->tp_free(self);
14853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
14863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
14883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_close(kqueue_queue_Object *self)
14893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
14903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    errno = kqueue_queue_internal_close(self);
14913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (errno < 0) {
14923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
14933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
14943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
14953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_RETURN_NONE;
14963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
14973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
14983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(kqueue_queue_close_doc,
14993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"close() -> None\n\
15003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
15013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielClose the kqueue control file descriptor. Further operations on the kqueue\n\
15023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielobject will raise an exception.");
15033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
15053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_get_closed(kqueue_queue_Object *self)
15063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
15073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->kqfd < 0)
15083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_RETURN_TRUE;
15093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else
15103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_RETURN_FALSE;
15113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
15123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
15143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_fileno(kqueue_queue_Object *self)
15153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
15163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->kqfd < 0)
15173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return kqueue_queue_err_closed();
15183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return PyInt_FromLong(self->kqfd);
15193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
15203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(kqueue_queue_fileno_doc,
15223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"fileno() -> int\n\
15233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
15243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielReturn the kqueue control file descriptor.");
15253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject*
15273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_fromfd(PyObject *cls, PyObject *args)
15283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
15293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SOCKET fd;
15303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
15323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
15333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return newKqueue_Object((PyTypeObject*)cls, fd);
15353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
15363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(kqueue_queue_fromfd_doc,
15383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"fromfd(fd) -> kqueue\n\
15393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
15403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielCreate a kqueue object from a given control fd.");
15413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyObject *
15433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielkqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
15443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
15453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int nevents = 0;
15463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int gotevents = 0;
15473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int nchanges = 0;
15483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    int i = 0;
15493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *otimeout = NULL;
15503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *ch = NULL;
15513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *it = NULL, *ei = NULL;
15523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *result = NULL;
15533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct kevent *evl = NULL;
15543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct kevent *chl = NULL;
15553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct timespec timeoutspec;
15563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    struct timespec *ptimeoutspec;
15573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (self->kqfd < 0)
15593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return kqueue_queue_err_closed();
15603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
15623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
15633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (nevents < 0) {
15653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_Format(PyExc_ValueError,
15663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            "Length of eventlist must be 0 or positive, got %d",
15673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            nevents);
15683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
15693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
15703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (otimeout == Py_None || otimeout == NULL) {
15723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ptimeoutspec = NULL;
15733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
15743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else if (PyNumber_Check(otimeout)) {
15753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        double timeout;
15763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        long seconds;
15773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = PyFloat_AsDouble(otimeout);
15793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (timeout == -1 && PyErr_Occurred())
15803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
15813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (timeout > (double)LONG_MAX) {
15823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_SetString(PyExc_OverflowError,
15833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                            "timeout period too long");
15843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
15853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
15863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (timeout < 0) {
15873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
15883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                            "timeout must be positive or None");
15893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
15903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
15913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
15923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        seconds = (long)timeout;
15933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeout = timeout - (double)seconds;
15943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeoutspec.tv_sec = seconds;
15953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        timeoutspec.tv_nsec = (long)(timeout * 1E9);
15963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ptimeoutspec = &timeoutspec;
15973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
15983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    else {
15993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_Format(PyExc_TypeError,
16003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            "timeout argument must be an number "
16013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            "or None, got %.200s",
16023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            Py_TYPE(otimeout)->tp_name);
16033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return NULL;
16043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
16053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (ch != NULL && ch != Py_None) {
16073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        it = PyObject_GetIter(ch);
16083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (it == NULL) {
16093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_SetString(PyExc_TypeError,
16103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                            "changelist is not iterable");
16113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            return NULL;
16123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
16133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        nchanges = PyObject_Size(ch);
16143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (nchanges < 0) {
16153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto error;
16163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
16173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        chl = PyMem_New(struct kevent, nchanges);
16193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (chl == NULL) {
16203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_NoMemory();
16213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto error;
16223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
16233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        i = 0;
16243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        while ((ei = PyIter_Next(it)) != NULL) {
16253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            if (!kqueue_event_Check(ei)) {
16263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                Py_DECREF(ei);
16273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                PyErr_SetString(PyExc_TypeError,
16283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                    "changelist must be an iterable of "
16293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                    "select.kevent objects");
16303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                goto error;
16313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            } else {
16323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                chl[i++] = ((kqueue_event_Object *)ei)->e;
16333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            }
16343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            Py_DECREF(ei);
16353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
16363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
16373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_CLEAR(it);
16383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* event list */
16403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (nevents) {
16413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        evl = PyMem_New(struct kevent, nevents);
16423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (evl == NULL) {
16433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_NoMemory();
16443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto error;
16453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
16463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
16473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_BEGIN_ALLOW_THREADS
16493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    gotevents = kevent(self->kqfd, chl, nchanges,
16503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel                       evl, nevents, ptimeoutspec);
16513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_END_ALLOW_THREADS
16523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (gotevents == -1) {
16543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyErr_SetFromErrno(PyExc_OSError);
16553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto error;
16563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
16573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    result = PyList_New(gotevents);
16593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (result == NULL) {
16603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        goto error;
16613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
16623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    for (i = 0; i < gotevents; i++) {
16643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        kqueue_event_Object *ch;
16653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
16673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (ch == NULL) {
16683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            goto error;
16693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
16703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        ch->e = evl[i];
16713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyList_SET_ITEM(result, i, (PyObject *)ch);
16723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
16733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_Free(chl);
16743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_Free(evl);
16753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return result;
16763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    error:
16783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_Free(chl);
16793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyMem_Free(evl);
16803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_XDECREF(result);
16813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_XDECREF(it);
16823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    return NULL;
16833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
16843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(kqueue_queue_control_doc,
16863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"control(changelist, max_events[, timeout=None]) -> eventlist\n\
16873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
16883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielCalls the kernel kevent function.\n\
16893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel- changelist must be a list of kevent objects describing the changes\n\
16903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  to be made to the kernel's watch list or None.\n\
16913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel- max_events lets you specify the maximum number of events that the\n\
16923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  kernel will return.\n\
16933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel- timeout is the maximum time to wait in seconds, or else None,\n\
16943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel  to wait forever. timeout accepts floats for smaller timeouts, too.");
16953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
16973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyMethodDef kqueue_queue_methods[] = {
16983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"fromfd",          (PyCFunction)kqueue_queue_fromfd,
16993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
17003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"close",           (PyCFunction)kqueue_queue_close,        METH_NOARGS,
17013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     kqueue_queue_close_doc},
17023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"fileno",          (PyCFunction)kqueue_queue_fileno,       METH_NOARGS,
17033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     kqueue_queue_fileno_doc},
17043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"control",         (PyCFunction)kqueue_queue_control,
17053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     METH_VARARGS ,     kqueue_queue_control_doc},
17063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {NULL,      NULL},
17073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
17083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
17093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyGetSetDef kqueue_queue_getsetlist[] = {
17103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"closed", (getter)kqueue_queue_get_closed, NULL,
17113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel     "True if the kqueue handler is closed"},
17123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {0},
17133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
17143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
17153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(kqueue_queue_doc,
17163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"Kqueue syscall wrapper.\n\
17173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielFor example, to start watching a socket for input:\n\
17193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel>>> kq = kqueue()\n\
17203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel>>> sock = socket()\n\
17213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel>>> sock.connect((host, port))\n\
17223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
17233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielTo wait one second for it to become writeable:\n\
17253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel>>> kq.control(None, 1, 1000)\n\
17263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielTo stop listening:\n\
17283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
17293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
17303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyTypeObject kqueue_queue_Type = {
17313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
17323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    "select.kqueue",                                    /* tp_name */
17333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    sizeof(kqueue_queue_Object),                        /* tp_basicsize */
17343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_itemsize */
17353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    (destructor)kqueue_queue_dealloc,                   /* tp_dealloc */
17363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_print */
17373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_getattr */
17383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_setattr */
17393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_compare */
17403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_repr */
17413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_number */
17423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_sequence */
17433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_mapping */
17443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_hash */
17453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_call */
17463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_str */
17473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_getattro */
17483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_setattro */
17493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_as_buffer */
17503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TPFLAGS_DEFAULT,                                 /* tp_flags */
17513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_queue_doc,                                   /* tp_doc */
17523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_traverse */
17533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_clear */
17543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_richcompare */
17553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_weaklistoffset */
17563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_iter */
17573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_iternext */
17583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_queue_methods,                               /* tp_methods */
17593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_members */
17603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_queue_getsetlist,                            /* tp_getset */
17613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_base */
17623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dict */
17633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_descr_get */
17643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_descr_set */
17653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_dictoffset */
17663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_init */
17673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_alloc */
17683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_queue_new,                                   /* tp_new */
17693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    0,                                                  /* tp_free */
17703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
17713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
17723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_KQUEUE */
17733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel/* ************************************************************************ */
17743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
17753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(select_doc,
17763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
17773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielWait until one or more file descriptors are ready for some kind of I/O.\n\
17793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielThe first three arguments are sequences of file descriptors to be waited for:\n\
17803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielrlist -- wait until ready for reading\n\
17813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielwlist -- wait until ready for writing\n\
17823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielxlist -- wait for an ``exceptional condition''\n\
17833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielIf only one kind of condition is required, pass [] for the other lists.\n\
17843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielA file descriptor is either a socket or file object, or a small integer\n\
17853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielgotten from a fileno() method call on one of those.\n\
17863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielThe optional 4th argument specifies a timeout in seconds; it may be\n\
17883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniela floating point number to specify fractions of seconds.  If it is absent\n\
17893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielor None, the call will never time out.\n\
17903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielThe return value is a tuple of three lists corresponding to the first three\n\
17923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielarguments; each contains the subset of the corresponding file descriptors\n\
17933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielthat are ready.\n\
17943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
17953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*** IMPORTANT NOTICE ***\n\
17963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielOn Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
17973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanieldescriptors can be used.");
17983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
17993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielstatic PyMethodDef select_methods[] = {
18003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"select",          select_select,  METH_VARARGS,   select_doc},
18013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
18023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {"poll",            select_poll,    METH_NOARGS,    poll_doc},
18033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_POLL */
18043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {0,         0},     /* sentinel */
18053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel};
18063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyDoc_STRVAR(module_doc,
18083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel"This module supports asynchronous I/O on multiple file descriptors.\n\
18093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel\n\
18103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel*** IMPORTANT NOTICE ***\n\
18113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielOn Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
18123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielPyMODINIT_FUNC
18143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDanielinitselect(void)
18153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel{
18163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyObject *m;
18173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    m = Py_InitModule3("select", select_methods, module_doc);
18183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (m == NULL)
18193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return;
18203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    SelectError = PyErr_NewException("select.error", NULL, NULL);
18223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(SelectError);
18233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddObject(m, "error", SelectError);
18243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef PIPE_BUF
18263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_BROKEN_PIPE_BUF
18273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#undef PIPE_BUF
18283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#define PIPE_BUF 512
18293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
18313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
18343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef __APPLE__
18353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (select_have_broken_poll()) {
18363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        if (PyObject_DelAttrString(m, "poll") == -1) {
18373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel            PyErr_Clear();
18383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        }
18393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    } else {
18403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#else
18413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    {
18423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        Py_TYPE(&poll_Type) = &PyType_Type;
18443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLIN", POLLIN);
18453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
18463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
18473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLERR", POLLERR);
18483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
18493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
18503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef POLLRDNORM
18523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
18533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef POLLRDBAND
18553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
18563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef POLLWRNORM
18583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
18593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef POLLWRBAND
18613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
18623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef POLLMSG
18643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
18653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    }
18673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_POLL */
18683ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18693ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_EPOLL
18703ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TYPE(&pyEpoll_Type) = &PyType_Type;
18713ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if (PyType_Ready(&pyEpoll_Type) < 0)
18723ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return;
18733ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18743ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(&pyEpoll_Type);
18753ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
18763ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18773ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
18783ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
18793ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
18803ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
18813ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
18823ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
18833ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef EPOLLONESHOT
18843ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* Kernel 2.6.2+ */
18853ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
18863ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
18873ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
18883ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
18893ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
18903ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
18913ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
18923ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
18933ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_EPOLL */
18943ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
18953ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef HAVE_KQUEUE
18963ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    kqueue_event_Type.tp_new = PyType_GenericNew;
18973ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TYPE(&kqueue_event_Type) = &PyType_Type;
18983ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if(PyType_Ready(&kqueue_event_Type) < 0)
18993ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return;
19003ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19013ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(&kqueue_event_Type);
19023ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
19033ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19043ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
19053ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    if(PyType_Ready(&kqueue_queue_Type) < 0)
19063ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel        return;
19073ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    Py_INCREF(&kqueue_queue_Type);
19083ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
19093ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19103ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* event filters */
19113ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
19123ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
19133ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
19143ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
19153ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
19163ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef EVFILT_NETDEV
19173ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
19183ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
19193ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
19203ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
19213ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19223ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* event flags */
19233ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
19243ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
19253ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
19263ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
19273ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
19283ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
19293ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19303ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
19313ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
19323ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19333ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
19343ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
19353ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19363ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* READ WRITE filter flag */
19373ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
19383ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19393ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* VNODE filter flags  */
19403ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
19413ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
19423ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
19433ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
19443ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
19453ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
19463ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
19473ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19483ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* PROC filter flags  */
19493ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
19503ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
19513ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
19523ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
19533ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
19543ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19553ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
19563ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
19573ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
19583ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19593ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    /* NETDEV filter flags */
19603ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#ifdef EVFILT_NETDEV
19613ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
19623ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
19633ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel    PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
19643ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif
19653ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel
19663ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel#endif /* HAVE_KQUEUE */
19673ec97ca490009ed5604ccd7f2653e5a9ecbf3474Daryl McDaniel}
1968