1
/* select - Module containing unix select(2) call.
2
Under Unix, the file descriptors are small integers.
3
Under Win32, select only exists for sockets, and sockets may
4
have any value except INVALID_SOCKET.
8
#include <structmember.h>
11
/* Perform runtime testing for a broken poll on OSX to make it easier
12
* to use the same binary on multiple releases of the OS.
14
#undef HAVE_BROKEN_POLL
17
/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
18
64 is too small (too many people have bumped into that limit).
20
Users who want even more than the boosted limit should #define
21
FD_SETSIZE higher before this; e.g., via compiler /D switch.
23
#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
24
#define FD_SETSIZE 512
27
#if defined(HAVE_POLL_H)
29
#elif defined(HAVE_SYS_POLL_H)
34
/* This is missing from unistd.h */
35
extern void bzero(void *, int);
38
#ifdef HAVE_SYS_TYPES_H
39
#include <sys/types.h>
42
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
48
# define WIN32_LEAN_AND_MEAN
57
static PyObject *SelectError;
59
/* list of Python objects and their file descriptor */
61
PyObject *obj; /* owned reference */
63
int sentinel; /* -1 == sentinel */
67
reap_obj(pylist fd2obj[FD_SETSIZE + 1])
70
for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
71
Py_XDECREF(fd2obj[i].obj);
74
fd2obj[0].sentinel = -1;
78
/* returns -1 and sets the Python exception if an error occurred, otherwise
82
seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
88
PyObject* fast_seq = NULL;
91
fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
94
fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences");
98
len = PySequence_Fast_GET_SIZE(fast_seq);
100
for (i = 0; i < len; i++) {
103
/* any intervening fileno() calls could decr this refcnt */
104
if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
108
v = PyObject_AsFileDescriptor( o );
109
if (v == -1) goto finally;
111
#if defined(_MSC_VER)
112
max = 0; /* not used for Win32 */
113
#else /* !_MSC_VER */
114
if (v < 0 || v >= FD_SETSIZE) {
115
PyErr_SetString(PyExc_ValueError,
116
"filedescriptor out of range in select()");
121
#endif /* _MSC_VER */
124
/* add object and its file descriptor to the list */
125
if (index >= FD_SETSIZE) {
126
PyErr_SetString(PyExc_ValueError,
127
"too many file descriptors in select()");
130
fd2obj[index].obj = o;
131
fd2obj[index].fd = v;
132
fd2obj[index].sentinel = 0;
133
fd2obj[++index].sentinel = -1;
144
/* returns NULL and sets the Python exception if an error occurred */
146
set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
152
for (j = 0; fd2obj[j].sentinel >= 0; j++) {
153
if (FD_ISSET(fd2obj[j].fd, set))
156
list = PyList_New(count);
161
for (j = 0; fd2obj[j].sentinel >= 0; j++) {
163
if (FD_ISSET(fd, set)) {
165
if (fd > FD_SETSIZE) {
166
PyErr_SetString(PyExc_SystemError,
167
"filedescriptor out of range returned in select()");
172
fd2obj[j].obj = NULL;
173
/* transfer ownership */
174
if (PyList_SetItem(list, i, o) < 0)
186
#undef SELECT_USES_HEAP
187
#if FD_SETSIZE > 1024
188
#define SELECT_USES_HEAP
189
#endif /* FD_SETSIZE > 1024 */
192
select_select(PyObject *self, PyObject *args)
194
#ifdef SELECT_USES_HEAP
195
pylist *rfd2obj, *wfd2obj, *efd2obj;
196
#else /* !SELECT_USES_HEAP */
197
/* XXX: All this should probably be implemented as follows:
198
* - find the highest descriptor we're interested in
201
* See: Stevens, APitUE, $12.5.1
203
pylist rfd2obj[FD_SETSIZE + 1];
204
pylist wfd2obj[FD_SETSIZE + 1];
205
pylist efd2obj[FD_SETSIZE + 1];
206
#endif /* SELECT_USES_HEAP */
207
PyObject *ifdlist, *ofdlist, *efdlist;
208
PyObject *ret = NULL;
209
PyObject *tout = Py_None;
210
fd_set ifdset, ofdset, efdset;
212
struct timeval tv, *tvp;
214
int imax, omax, emax, max;
217
/* convert arguments */
218
if (!PyArg_UnpackTuple(args, "select", 3, 4,
219
&ifdlist, &ofdlist, &efdlist, &tout))
223
tvp = (struct timeval *)0;
224
else if (!PyNumber_Check(tout)) {
225
PyErr_SetString(PyExc_TypeError,
226
"timeout must be a float or None");
230
timeout = PyFloat_AsDouble(tout);
231
if (timeout == -1 && PyErr_Occurred())
233
if (timeout > (double)LONG_MAX) {
234
PyErr_SetString(PyExc_OverflowError,
235
"timeout period too long");
238
seconds = (long)timeout;
239
timeout = timeout - (double)seconds;
241
tv.tv_usec = (long)(timeout * 1E6);
246
#ifdef SELECT_USES_HEAP
247
/* Allocate memory for the lists */
248
rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
249
wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
250
efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
251
if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
252
if (rfd2obj) PyMem_DEL(rfd2obj);
253
if (wfd2obj) PyMem_DEL(wfd2obj);
254
if (efd2obj) PyMem_DEL(efd2obj);
255
return PyErr_NoMemory();
257
#endif /* SELECT_USES_HEAP */
258
/* Convert sequences to fd_sets, and get maximum fd number
259
* propagates the Python exception set in seq2set()
261
rfd2obj[0].sentinel = -1;
262
wfd2obj[0].sentinel = -1;
263
efd2obj[0].sentinel = -1;
264
if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
266
if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
268
if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
271
if (omax > max) max = omax;
272
if (emax > max) max = emax;
274
Py_BEGIN_ALLOW_THREADS
275
n = select(max, &ifdset, &ofdset, &efdset, tvp);
279
if (n == SOCKET_ERROR) {
280
PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
284
PyErr_SetFromErrno(SelectError);
289
ifdlist = PyList_New(0);
291
ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist);
296
/* any of these three calls can raise an exception. it's more
297
convenient to test for this after all three calls... but
300
ifdlist = set2list(&ifdset, rfd2obj);
301
ofdlist = set2list(&ofdset, wfd2obj);
302
efdlist = set2list(&efdset, efd2obj);
303
if (PyErr_Occurred())
306
ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
317
#ifdef SELECT_USES_HEAP
321
#endif /* SELECT_USES_HEAP */
325
#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
338
static PyTypeObject poll_Type;
340
/* Update the malloc'ed array of pollfds to match the dictionary
341
contained within a pollObject. Return 1 on success, 0 on an error.
345
update_ufd_array(pollObject *self)
348
PyObject *key, *value;
349
struct pollfd *old_ufds = self->ufds;
351
self->ufd_len = PyDict_Size(self->dict);
352
PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
353
if (self->ufds == NULL) {
354
self->ufds = old_ufds;
360
while (PyDict_Next(self->dict, &pos, &key, &value)) {
361
self->ufds[i].fd = PyLong_AsLong(key);
362
self->ufds[i].events = (short)PyLong_AsLong(value);
365
self->ufd_uptodate = 1;
369
PyDoc_STRVAR(poll_register_doc,
370
"register(fd [, eventmask] ) -> None\n\n\
371
Register a file descriptor with the polling object.\n\
372
fd -- either an integer, or an object with a fileno() method returning an\n\
374
events -- an optional bitmask describing the type of events to check for");
377
poll_register(pollObject *self, PyObject *args)
379
PyObject *o, *key, *value;
380
int fd, events = POLLIN | POLLPRI | POLLOUT;
383
if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
387
fd = PyObject_AsFileDescriptor(o);
388
if (fd == -1) return NULL;
390
/* Add entry to the internal dictionary: the key is the
391
file descriptor, and the value is the event mask. */
392
key = PyLong_FromLong(fd);
395
value = PyLong_FromLong(events);
400
err = PyDict_SetItem(self->dict, key, value);
406
self->ufd_uptodate = 0;
412
PyDoc_STRVAR(poll_modify_doc,
413
"modify(fd, eventmask) -> None\n\n\
414
Modify an already registered file descriptor.\n\
415
fd -- either an integer, or an object with a fileno() method returning an\n\
417
events -- an optional bitmask describing the type of events to check for");
420
poll_modify(pollObject *self, PyObject *args)
422
PyObject *o, *key, *value;
426
if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) {
430
fd = PyObject_AsFileDescriptor(o);
431
if (fd == -1) return NULL;
433
/* Modify registered fd */
434
key = PyLong_FromLong(fd);
437
if (PyDict_GetItem(self->dict, key) == NULL) {
439
PyErr_SetFromErrno(PyExc_IOError);
442
value = PyLong_FromLong(events);
447
err = PyDict_SetItem(self->dict, key, value);
453
self->ufd_uptodate = 0;
460
PyDoc_STRVAR(poll_unregister_doc,
461
"unregister(fd) -> None\n\n\
462
Remove a file descriptor being tracked by the polling object.");
465
poll_unregister(pollObject *self, PyObject *o)
470
fd = PyObject_AsFileDescriptor( o );
474
/* Check whether the fd is already in the array */
475
key = PyLong_FromLong(fd);
479
if (PyDict_DelItem(self->dict, key) == -1) {
481
/* This will simply raise the KeyError set by PyDict_DelItem
482
if the file descriptor isn't registered. */
487
self->ufd_uptodate = 0;
493
PyDoc_STRVAR(poll_poll_doc,
494
"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
495
Polls the set of registered file descriptors, returning a list containing \n\
496
any descriptors that have events or errors to report.");
499
poll_poll(pollObject *self, PyObject *args)
501
PyObject *result_list = NULL, *tout = NULL;
502
int timeout = 0, poll_result, i, j;
503
PyObject *value = NULL, *num = NULL;
505
if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
509
/* Check values for timeout */
510
if (tout == NULL || tout == Py_None)
512
else if (!PyNumber_Check(tout)) {
513
PyErr_SetString(PyExc_TypeError,
514
"timeout must be an integer or None");
518
tout = PyNumber_Long(tout);
521
timeout = PyLong_AsLong(tout);
523
if (timeout == -1 && PyErr_Occurred())
527
/* Ensure the ufd array is up to date */
528
if (!self->ufd_uptodate)
529
if (update_ufd_array(self) == 0)
533
Py_BEGIN_ALLOW_THREADS
534
poll_result = poll(self->ufds, self->ufd_len, timeout);
537
if (poll_result < 0) {
538
PyErr_SetFromErrno(SelectError);
542
/* build the result list */
544
result_list = PyList_New(poll_result);
548
for (i = 0, j = 0; j < poll_result; j++) {
549
/* skip to the next fired descriptor */
550
while (!self->ufds[i].revents) {
553
/* if we hit a NULL return, set value to NULL
554
and break out of loop; code at end will
555
clean up result_list */
556
value = PyTuple_New(2);
559
num = PyLong_FromLong(self->ufds[i].fd);
564
PyTuple_SET_ITEM(value, 0, num);
566
/* The &0xffff is a workaround for AIX. 'revents'
567
is a 16-bit short, and IBM assigned POLLNVAL
568
to be 0x8000, so the conversion to int results
569
in a negative number. See SF bug #923315. */
570
num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
575
PyTuple_SET_ITEM(value, 1, num);
576
if ((PyList_SetItem(result_list, j, value)) == -1) {
586
Py_DECREF(result_list);
590
static PyMethodDef poll_methods[] = {
591
{"register", (PyCFunction)poll_register,
592
METH_VARARGS, poll_register_doc},
593
{"modify", (PyCFunction)poll_modify,
594
METH_VARARGS, poll_modify_doc},
595
{"unregister", (PyCFunction)poll_unregister,
596
METH_O, poll_unregister_doc},
597
{"poll", (PyCFunction)poll_poll,
598
METH_VARARGS, poll_poll_doc},
599
{NULL, NULL} /* sentinel */
606
self = PyObject_New(pollObject, &poll_Type);
609
/* ufd_uptodate is a Boolean, denoting whether the
610
array pointed to by ufds matches the contents of the dictionary. */
611
self->ufd_uptodate = 0;
613
self->dict = PyDict_New();
614
if (self->dict == NULL) {
622
poll_dealloc(pollObject *self)
624
if (self->ufds != NULL)
625
PyMem_DEL(self->ufds);
626
Py_XDECREF(self->dict);
630
static PyTypeObject poll_Type = {
631
/* The ob_type field must be initialized in the module init function
632
* to be portable to Windows without using C++. */
633
PyVarObject_HEAD_INIT(NULL, 0)
634
"select.poll", /*tp_name*/
635
sizeof(pollObject), /*tp_basicsize*/
638
(destructor)poll_dealloc, /*tp_dealloc*/
645
0, /*tp_as_sequence*/
653
Py_TPFLAGS_DEFAULT, /*tp_flags*/
657
0, /*tp_richcompare*/
658
0, /*tp_weaklistoffset*/
661
poll_methods, /*tp_methods*/
664
PyDoc_STRVAR(poll_doc,
665
"Returns a polling object, which supports registering and\n\
666
unregistering file descriptors, and then polling them for I/O events.");
669
select_poll(PyObject *self, PyObject *unused)
671
return (PyObject *)newPollObject();
676
* On some systems poll() sets errno on invalid file descriptors. We test
677
* for this at runtime because this bug may be fixed or introduced between
680
static int select_have_broken_poll(void)
685
struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
687
/* Create a file descriptor to make invalid */
688
if (pipe(filedes) < 0) {
691
poll_struct.fd = filedes[0];
694
poll_test = poll(&poll_struct, 1, 0);
697
} else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
702
#endif /* __APPLE__ */
704
#endif /* HAVE_POLL */
707
/* **************************************************************************
708
* epoll interface for Linux 2.6
710
* Written by Christian Heimes
711
* Inspired by Twisted's _epoll.pyx and select.poll()
714
#ifdef HAVE_SYS_EPOLL_H
715
#include <sys/epoll.h>
720
SOCKET epfd; /* epoll control file descriptor */
723
static PyTypeObject pyEpoll_Type;
724
#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
727
pyepoll_err_closed(void)
729
PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
734
pyepoll_internal_close(pyEpoll_Object *self)
737
if (self->epfd >= 0) {
738
int epfd = self->epfd;
740
Py_BEGIN_ALLOW_THREADS
749
newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
751
pyEpoll_Object *self;
753
if (sizehint == -1) {
754
sizehint = FD_SETSIZE-1;
756
else if (sizehint < 1) {
757
PyErr_Format(PyExc_ValueError,
758
"sizehint must be greater zero, got %d",
763
assert(type != NULL && type->tp_alloc != NULL);
764
self = (pyEpoll_Object *) type->tp_alloc(type, 0);
769
Py_BEGIN_ALLOW_THREADS
770
self->epfd = epoll_create(sizehint);
776
if (self->epfd < 0) {
778
PyErr_SetFromErrno(PyExc_IOError);
781
return (PyObject *)self;
786
pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
789
static char *kwlist[] = {"sizehint", NULL};
791
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
795
return newPyEpoll_Object(type, sizehint, -1);
800
pyepoll_dealloc(pyEpoll_Object *self)
802
(void)pyepoll_internal_close(self);
803
Py_TYPE(self)->tp_free(self);
807
pyepoll_close(pyEpoll_Object *self)
809
errno = pyepoll_internal_close(self);
811
PyErr_SetFromErrno(PyExc_IOError);
817
PyDoc_STRVAR(pyepoll_close_doc,
820
Close the epoll control file descriptor. Further operations on the epoll\n\
821
object will raise an exception.");
824
pyepoll_get_closed(pyEpoll_Object *self)
833
pyepoll_fileno(pyEpoll_Object *self)
836
return pyepoll_err_closed();
837
return PyLong_FromLong(self->epfd);
840
PyDoc_STRVAR(pyepoll_fileno_doc,
843
Return the epoll control file descriptor.");
846
pyepoll_fromfd(PyObject *cls, PyObject *args)
850
if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
853
return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
856
PyDoc_STRVAR(pyepoll_fromfd_doc,
857
"fromfd(fd) -> epoll\n\
859
Create an epoll object from a given control fd.");
862
pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
864
struct epoll_event ev;
869
return pyepoll_err_closed();
871
fd = PyObject_AsFileDescriptor(pfd);
881
Py_BEGIN_ALLOW_THREADS
882
result = epoll_ctl(epfd, op, fd, &ev);
886
/* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
887
* operation required a non-NULL pointer in event, even
888
* though this argument is ignored. */
889
Py_BEGIN_ALLOW_THREADS
890
result = epoll_ctl(epfd, op, fd, &ev);
891
if (errno == EBADF) {
892
/* fd already closed */
904
PyErr_SetFromErrno(PyExc_IOError);
911
pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
914
unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
915
static char *kwlist[] = {"fd", "eventmask", NULL};
917
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
922
return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
925
PyDoc_STRVAR(pyepoll_register_doc,
926
"register(fd[, eventmask]) -> bool\n\
928
Registers a new fd or modifies an already registered fd. register() returns\n\
929
True if a new fd was registered or False if the event mask for fd was modified.\n\
930
fd is the target file descriptor of the operation.\n\
931
events is a bit set composed of the various EPOLL constants; the default\n\
932
is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
934
The epoll interface supports all file descriptors that support poll.");
937
pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
941
static char *kwlist[] = {"fd", "eventmask", NULL};
943
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
948
return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
951
PyDoc_STRVAR(pyepoll_modify_doc,
952
"modify(fd, eventmask) -> None\n\
954
fd is the target file descriptor of the operation\n\
955
events is a bit set composed of the various EPOLL constants");
958
pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
961
static char *kwlist[] = {"fd", NULL};
963
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
968
return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
971
PyDoc_STRVAR(pyepoll_unregister_doc,
972
"unregister(fd) -> None\n\
974
fd is the target file descriptor of the operation.");
977
pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
979
double dtimeout = -1.;
983
PyObject *elist = NULL, *etuple = NULL;
984
struct epoll_event *evs = NULL;
985
static char *kwlist[] = {"timeout", "maxevents", NULL};
988
return pyepoll_err_closed();
990
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
991
&dtimeout, &maxevents)) {
998
else if (dtimeout * 1000.0 > INT_MAX) {
999
PyErr_SetString(PyExc_OverflowError,
1000
"timeout is too large");
1004
timeout = (int)(dtimeout * 1000.0);
1007
if (maxevents == -1) {
1008
maxevents = FD_SETSIZE-1;
1010
else if (maxevents < 1) {
1011
PyErr_Format(PyExc_ValueError,
1012
"maxevents must be greater than 0, got %d",
1017
evs = PyMem_New(struct epoll_event, maxevents);
1024
Py_BEGIN_ALLOW_THREADS
1025
nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
1026
Py_END_ALLOW_THREADS
1028
PyErr_SetFromErrno(PyExc_IOError);
1032
elist = PyList_New(nfds);
1033
if (elist == NULL) {
1037
for (i = 0; i < nfds; i++) {
1038
etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1039
if (etuple == NULL) {
1043
PyList_SET_ITEM(elist, i, etuple);
1051
PyDoc_STRVAR(pyepoll_poll_doc,
1052
"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1054
Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1055
in seconds (as float). -1 makes poll wait indefinitely.\n\
1056
Up to maxevents are returned to the caller.");
1058
static PyMethodDef pyepoll_methods[] = {
1059
{"fromfd", (PyCFunction)pyepoll_fromfd,
1060
METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1061
{"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1063
{"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1064
pyepoll_fileno_doc},
1065
{"modify", (PyCFunction)pyepoll_modify,
1066
METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1067
{"register", (PyCFunction)pyepoll_register,
1068
METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1069
{"unregister", (PyCFunction)pyepoll_unregister,
1070
METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1071
{"poll", (PyCFunction)pyepoll_poll,
1072
METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
1076
static PyGetSetDef pyepoll_getsetlist[] = {
1077
{"closed", (getter)pyepoll_get_closed, NULL,
1078
"True if the epoll handler is closed"},
1082
PyDoc_STRVAR(pyepoll_doc,
1083
"select.epoll([sizehint=-1])\n\
1085
Returns an epolling object\n\
1087
sizehint must be a positive integer or -1 for the default size. The\n\
1088
sizehint is used to optimize internal data structures. It doesn't limit\n\
1089
the maximum number of monitored events.");
1091
static PyTypeObject pyEpoll_Type = {
1092
PyVarObject_HEAD_INIT(NULL, 0)
1093
"select.epoll", /* tp_name */
1094
sizeof(pyEpoll_Object), /* tp_basicsize */
1095
0, /* tp_itemsize */
1096
(destructor)pyepoll_dealloc, /* tp_dealloc */
1100
0, /* tp_reserved */
1102
0, /* tp_as_number */
1103
0, /* tp_as_sequence */
1104
0, /* tp_as_mapping */
1108
PyObject_GenericGetAttr, /* tp_getattro */
1109
0, /* tp_setattro */
1110
0, /* tp_as_buffer */
1111
Py_TPFLAGS_DEFAULT, /* tp_flags */
1112
pyepoll_doc, /* tp_doc */
1113
0, /* tp_traverse */
1115
0, /* tp_richcompare */
1116
0, /* tp_weaklistoffset */
1118
0, /* tp_iternext */
1119
pyepoll_methods, /* tp_methods */
1121
pyepoll_getsetlist, /* tp_getset */
1124
0, /* tp_descr_get */
1125
0, /* tp_descr_set */
1126
0, /* tp_dictoffset */
1129
pyepoll_new, /* tp_new */
1133
#endif /* HAVE_EPOLL */
1136
/* **************************************************************************
1137
* kqueue interface for BSD
1139
* Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1140
* All rights reserved.
1142
* Redistribution and use in source and binary forms, with or without
1143
* modification, are permitted provided that the following conditions
1145
* 1. Redistributions of source code must retain the above copyright
1146
* notice, this list of conditions and the following disclaimer.
1147
* 2. Redistributions in binary form must reproduce the above copyright
1148
* notice, this list of conditions and the following disclaimer in the
1149
* documentation and/or other materials provided with the distribution.
1151
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1152
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1153
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1154
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1155
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1156
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1157
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1158
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1159
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1160
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1164
#ifdef HAVE_SYS_EVENT_H
1165
#include <sys/event.h>
1168
PyDoc_STRVAR(kqueue_event_doc,
1169
"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0)\n\
1171
This object is the equivalent of the struct kevent for the C API.\n\
1173
See the kqueue manpage for more detailed information about the meaning\n\
1174
of the arguments.\n\
1176
One minor note: while you might hope that udata could store a\n\
1177
reference to a python object, it cannot, because it is impossible to\n\
1178
keep a proper reference count of the object once it's passed into the\n\
1179
kernel. Therefore, I have restricted it to only storing an integer. I\n\
1180
recommend ignoring it and simply using the 'ident' field to key off\n\
1181
of. You could also set up a dictionary on the python side to store a\n\
1182
udata->object mapping.");
1187
} kqueue_event_Object;
1189
static PyTypeObject kqueue_event_Type;
1191
#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1195
SOCKET kqfd; /* kqueue control fd */
1196
} kqueue_queue_Object;
1198
static PyTypeObject kqueue_queue_Type;
1200
#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1202
/* Unfortunately, we can't store python objects in udata, because
1203
* kevents in the kernel can be removed without warning, which would
1204
* forever lose the refcount on the object stored with it.
1207
#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1208
static struct PyMemberDef kqueue_event_members[] = {
1209
{"ident", T_UINT, KQ_OFF(e.ident)},
1210
{"filter", T_SHORT, KQ_OFF(e.filter)},
1211
{"flags", T_USHORT, KQ_OFF(e.flags)},
1212
{"fflags", T_UINT, KQ_OFF(e.fflags)},
1213
{"data", T_INT, KQ_OFF(e.data)},
1214
{"udata", T_INT, KQ_OFF(e.udata)},
1215
{NULL} /* Sentinel */
1220
kqueue_event_repr(kqueue_event_Object *s)
1225
"<select.kevent ident=%lu filter=%d flags=0x%x fflags=0x%x "
1226
"data=0x%lx udata=%p>",
1227
(unsigned long)(s->e.ident), s->e.filter, s->e.flags,
1228
s->e.fflags, (long)(s->e.data), s->e.udata);
1229
return PyBytes_FromString(buf);
1233
kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1236
static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1237
"data", "udata", NULL};
1239
EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1241
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist,
1242
&pfd, &(self->e.filter), &(self->e.flags),
1243
&(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1247
self->e.ident = PyObject_AsFileDescriptor(pfd);
1248
if (self->e.ident == -1) {
1255
kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1260
if (!kqueue_event_Check(o)) {
1261
if (op == Py_EQ || op == Py_NE) {
1262
PyObject *res = op == Py_EQ ? Py_False : Py_True;
1266
PyErr_Format(PyExc_TypeError,
1267
"can't compare %.200s to %.200s",
1268
Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1271
if (((result = s->e.ident - o->e.ident) == 0) &&
1272
((result = s->e.filter - o->e.filter) == 0) &&
1273
((result = s->e.flags - o->e.flags) == 0) &&
1274
((result = s->e.fflags - o->e.fflags) == 0) &&
1275
((result = s->e.data - o->e.data) == 0) &&
1276
((result = s->e.udata - o->e.udata) == 0)
1283
result = (result == 0);
1286
result = (result != 0);
1289
result = (result <= 0);
1292
result = (result >= 0);
1295
result = (result < 0);
1298
result = (result > 0);
1301
return PyBool_FromLong(result);
1304
static PyTypeObject kqueue_event_Type = {
1305
PyVarObject_HEAD_INIT(NULL, 0)
1306
"select.kevent", /* tp_name */
1307
sizeof(kqueue_event_Object), /* tp_basicsize */
1308
0, /* tp_itemsize */
1313
0, /* tp_reserved */
1314
(reprfunc)kqueue_event_repr, /* tp_repr */
1315
0, /* tp_as_number */
1316
0, /* tp_as_sequence */
1317
0, /* tp_as_mapping */
1321
0, /* tp_getattro */
1322
0, /* tp_setattro */
1323
0, /* tp_as_buffer */
1324
Py_TPFLAGS_DEFAULT, /* tp_flags */
1325
kqueue_event_doc, /* tp_doc */
1326
0, /* tp_traverse */
1328
(richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1329
0, /* tp_weaklistoffset */
1331
0, /* tp_iternext */
1333
kqueue_event_members, /* tp_members */
1337
0, /* tp_descr_get */
1338
0, /* tp_descr_set */
1339
0, /* tp_dictoffset */
1340
(initproc)kqueue_event_init, /* tp_init */
1347
kqueue_queue_err_closed(void)
1349
PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
1354
kqueue_queue_internal_close(kqueue_queue_Object *self)
1357
if (self->kqfd >= 0) {
1358
int kqfd = self->kqfd;
1360
Py_BEGIN_ALLOW_THREADS
1361
if (close(kqfd) < 0)
1363
Py_END_ALLOW_THREADS
1369
newKqueue_Object(PyTypeObject *type, SOCKET fd)
1371
kqueue_queue_Object *self;
1372
assert(type != NULL && type->tp_alloc != NULL);
1373
self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1379
Py_BEGIN_ALLOW_THREADS
1380
self->kqfd = kqueue();
1381
Py_END_ALLOW_THREADS
1386
if (self->kqfd < 0) {
1388
PyErr_SetFromErrno(PyExc_IOError);
1391
return (PyObject *)self;
1395
kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1398
if ((args != NULL && PyObject_Size(args)) ||
1399
(kwds != NULL && PyObject_Size(kwds))) {
1400
PyErr_SetString(PyExc_ValueError,
1401
"select.kqueue doesn't accept arguments");
1405
return newKqueue_Object(type, -1);
1409
kqueue_queue_dealloc(kqueue_queue_Object *self)
1411
kqueue_queue_internal_close(self);
1412
Py_TYPE(self)->tp_free(self);
1416
kqueue_queue_close(kqueue_queue_Object *self)
1418
errno = kqueue_queue_internal_close(self);
1420
PyErr_SetFromErrno(PyExc_IOError);
1426
PyDoc_STRVAR(kqueue_queue_close_doc,
1429
Close the kqueue control file descriptor. Further operations on the kqueue\n\
1430
object will raise an exception.");
1433
kqueue_queue_get_closed(kqueue_queue_Object *self)
1442
kqueue_queue_fileno(kqueue_queue_Object *self)
1445
return kqueue_queue_err_closed();
1446
return PyLong_FromLong(self->kqfd);
1449
PyDoc_STRVAR(kqueue_queue_fileno_doc,
1452
Return the kqueue control file descriptor.");
1455
kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1459
if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1462
return newKqueue_Object((PyTypeObject*)cls, fd);
1465
PyDoc_STRVAR(kqueue_queue_fromfd_doc,
1466
"fromfd(fd) -> kqueue\n\
1468
Create a kqueue object from a given control fd.");
1471
kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
1477
PyObject *otimeout = NULL;
1478
PyObject *ch = NULL;
1479
PyObject *it = NULL, *ei = NULL;
1480
PyObject *result = NULL;
1481
struct kevent *evl = NULL;
1482
struct kevent *chl = NULL;
1483
struct timespec timeoutspec;
1484
struct timespec *ptimeoutspec;
1487
return kqueue_queue_err_closed();
1489
if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
1493
PyErr_Format(PyExc_ValueError,
1494
"Length of eventlist must be 0 or positive, got %d",
1499
if (ch != NULL && ch != Py_None) {
1500
it = PyObject_GetIter(ch);
1502
PyErr_SetString(PyExc_TypeError,
1503
"changelist is not iterable");
1506
nchanges = PyObject_Size(ch);
1512
if (otimeout == Py_None || otimeout == NULL) {
1513
ptimeoutspec = NULL;
1515
else if (PyNumber_Check(otimeout)) {
1519
timeout = PyFloat_AsDouble(otimeout);
1520
if (timeout == -1 && PyErr_Occurred())
1522
if (timeout > (double)LONG_MAX) {
1523
PyErr_SetString(PyExc_OverflowError,
1524
"timeout period too long");
1528
PyErr_SetString(PyExc_ValueError,
1529
"timeout must be positive or None");
1533
seconds = (long)timeout;
1534
timeout = timeout - (double)seconds;
1535
timeoutspec.tv_sec = seconds;
1536
timeoutspec.tv_nsec = (long)(timeout * 1E9);
1537
ptimeoutspec = &timeoutspec;
1540
PyErr_Format(PyExc_TypeError,
1541
"timeout argument must be an number "
1542
"or None, got %.200s",
1543
Py_TYPE(otimeout)->tp_name);
1548
chl = PyMem_New(struct kevent, nchanges);
1553
while ((ei = PyIter_Next(it)) != NULL) {
1554
if (!kqueue_event_Check(ei)) {
1556
PyErr_SetString(PyExc_TypeError,
1557
"changelist must be an iterable of "
1558
"select.kevent objects");
1561
chl[i] = ((kqueue_event_Object *)ei)->e;
1570
evl = PyMem_New(struct kevent, nevents);
1577
Py_BEGIN_ALLOW_THREADS
1578
gotevents = kevent(self->kqfd, chl, nchanges,
1579
evl, nevents, ptimeoutspec);
1580
Py_END_ALLOW_THREADS
1582
if (gotevents == -1) {
1583
PyErr_SetFromErrno(PyExc_OSError);
1587
result = PyList_New(gotevents);
1588
if (result == NULL) {
1592
for (i=0; i < gotevents; i++) {
1593
kqueue_event_Object *ch;
1595
ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
1600
PyList_SET_ITEM(result, i, (PyObject *)ch);
1614
PyDoc_STRVAR(kqueue_queue_control_doc,
1615
"control(changelist, max_events[, timeout=None]) -> eventlist\n\
1617
Calls the kernel kevent function.\n\
1618
- changelist must be a list of kevent objects describing the changes\n\
1619
to be made to the kernel's watch list or None.\n\
1620
- max_events lets you specify the maximum number of events that the\n\
1621
kernel will return.\n\
1622
- timeout is the maximum time to wait in seconds, or else None,\n\
1623
to wait forever. timeout accepts floats for smaller timeouts, too.");
1626
static PyMethodDef kqueue_queue_methods[] = {
1627
{"fromfd", (PyCFunction)kqueue_queue_fromfd,
1628
METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
1629
{"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
1630
kqueue_queue_close_doc},
1631
{"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
1632
kqueue_queue_fileno_doc},
1633
{"control", (PyCFunction)kqueue_queue_control,
1634
METH_VARARGS , kqueue_queue_control_doc},
1638
static PyGetSetDef kqueue_queue_getsetlist[] = {
1639
{"closed", (getter)kqueue_queue_get_closed, NULL,
1640
"True if the kqueue handler is closed"},
1644
PyDoc_STRVAR(kqueue_queue_doc,
1645
"Kqueue syscall wrapper.\n\
1647
For example, to start watching a socket for input:\n\
1648
>>> kq = kqueue()\n\
1649
>>> sock = socket()\n\
1650
>>> sock.connect((host, port))\n\
1651
>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
1653
To wait one second for it to become writeable:\n\
1654
>>> kq.control(None, 1, 1000)\n\
1656
To stop listening:\n\
1657
>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
1659
static PyTypeObject kqueue_queue_Type = {
1660
PyVarObject_HEAD_INIT(NULL, 0)
1661
"select.kqueue", /* tp_name */
1662
sizeof(kqueue_queue_Object), /* tp_basicsize */
1663
0, /* tp_itemsize */
1664
(destructor)kqueue_queue_dealloc, /* tp_dealloc */
1668
0, /* tp_reserved */
1670
0, /* tp_as_number */
1671
0, /* tp_as_sequence */
1672
0, /* tp_as_mapping */
1676
0, /* tp_getattro */
1677
0, /* tp_setattro */
1678
0, /* tp_as_buffer */
1679
Py_TPFLAGS_DEFAULT, /* tp_flags */
1680
kqueue_queue_doc, /* tp_doc */
1681
0, /* tp_traverse */
1683
0, /* tp_richcompare */
1684
0, /* tp_weaklistoffset */
1686
0, /* tp_iternext */
1687
kqueue_queue_methods, /* tp_methods */
1689
kqueue_queue_getsetlist, /* tp_getset */
1692
0, /* tp_descr_get */
1693
0, /* tp_descr_set */
1694
0, /* tp_dictoffset */
1697
kqueue_queue_new, /* tp_new */
1701
#endif /* HAVE_KQUEUE */
1702
/* ************************************************************************ */
1704
PyDoc_STRVAR(select_doc,
1705
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
1707
Wait until one or more file descriptors are ready for some kind of I/O.\n\
1708
The first three arguments are sequences of file descriptors to be waited for:\n\
1709
rlist -- wait until ready for reading\n\
1710
wlist -- wait until ready for writing\n\
1711
xlist -- wait for an ``exceptional condition''\n\
1712
If only one kind of condition is required, pass [] for the other lists.\n\
1713
A file descriptor is either a socket or file object, or a small integer\n\
1714
gotten from a fileno() method call on one of those.\n\
1716
The optional 4th argument specifies a timeout in seconds; it may be\n\
1717
a floating point number to specify fractions of seconds. If it is absent\n\
1718
or None, the call will never time out.\n\
1720
The return value is a tuple of three lists corresponding to the first three\n\
1721
arguments; each contains the subset of the corresponding file descriptors\n\
1724
*** IMPORTANT NOTICE ***\n\
1725
On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
1726
descriptors can be used.");
1728
static PyMethodDef select_methods[] = {
1729
{"select", select_select, METH_VARARGS, select_doc},
1731
{"poll", select_poll, METH_NOARGS, poll_doc},
1732
#endif /* HAVE_POLL */
1733
{0, 0}, /* sentinel */
1736
PyDoc_STRVAR(module_doc,
1737
"This module supports asynchronous I/O on multiple file descriptors.\n\
1739
*** IMPORTANT NOTICE ***\n\
1740
On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
1743
static struct PyModuleDef selectmodule = {
1744
PyModuleDef_HEAD_INIT,
1759
m = PyModule_Create(&selectmodule);
1763
SelectError = PyErr_NewException("select.error", NULL, NULL);
1764
Py_INCREF(SelectError);
1765
PyModule_AddObject(m, "error", SelectError);
1767
#if defined(HAVE_POLL)
1769
if (select_have_broken_poll()) {
1770
if (PyObject_DelAttrString(m, "poll") == -1) {
1777
if (PyType_Ready(&poll_Type) < 0)
1779
PyModule_AddIntConstant(m, "POLLIN", POLLIN);
1780
PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
1781
PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
1782
PyModule_AddIntConstant(m, "POLLERR", POLLERR);
1783
PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
1784
PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
1787
PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
1790
PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
1793
PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
1796
PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
1799
PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
1802
#endif /* HAVE_POLL */
1805
Py_TYPE(&pyEpoll_Type) = &PyType_Type;
1806
if (PyType_Ready(&pyEpoll_Type) < 0)
1809
Py_INCREF(&pyEpoll_Type);
1810
PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
1812
PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
1813
PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
1814
PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
1815
PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
1816
PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
1817
PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
1820
PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
1822
/* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
1823
PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
1824
PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
1825
PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
1826
PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
1827
PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
1828
#endif /* HAVE_EPOLL */
1831
kqueue_event_Type.tp_new = PyType_GenericNew;
1832
Py_TYPE(&kqueue_event_Type) = &PyType_Type;
1833
if(PyType_Ready(&kqueue_event_Type) < 0)
1836
Py_INCREF(&kqueue_event_Type);
1837
PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
1839
Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
1840
if(PyType_Ready(&kqueue_queue_Type) < 0)
1842
Py_INCREF(&kqueue_queue_Type);
1843
PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
1846
PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
1847
PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
1848
PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
1849
PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
1850
PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
1851
#ifdef EVFILT_NETDEV
1852
PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
1854
PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
1855
PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
1858
PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
1859
PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
1860
PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
1861
PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
1862
PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
1863
PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
1865
PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
1866
PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
1868
PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
1869
PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
1871
/* READ WRITE filter flag */
1872
PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
1874
/* VNODE filter flags */
1875
PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
1876
PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
1877
PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
1878
PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
1879
PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
1880
PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
1881
PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
1883
/* PROC filter flags */
1884
PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
1885
PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
1886
PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
1887
PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
1888
PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
1890
PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
1891
PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
1892
PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
1894
/* NETDEV filter flags */
1895
#ifdef EVFILT_NETDEV
1896
PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
1897
PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
1898
PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
1901
#endif /* HAVE_KQUEUE */