blob: 3b7713abab3693cadf22b94fdbef851dab50dbf7 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 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.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Berker Peksagfe8d9662016-07-19 21:09:26 +03007#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
8#define _GNU_SOURCE
9#endif
10
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000011#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +000012#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000013
Jesus Cead8b9ae62011-11-14 19:07:41 +010014#ifdef HAVE_SYS_DEVPOLL_H
15#include <sys/resource.h>
16#include <sys/devpoll.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#endif
21
Thomas Wouters477c8d52006-05-27 19:21:47 +000022#ifdef __APPLE__
23 /* Perform runtime testing for a broken poll on OSX to make it easier
24 * to use the same binary on multiple releases of the OS.
25 */
26#undef HAVE_BROKEN_POLL
27#endif
28
Tim Petersd92dfe02000-12-12 01:18:41 +000029/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
30 64 is too small (too many people have bumped into that limit).
31 Here we boost it.
32 Users who want even more than the boosted limit should #define
33 FD_SETSIZE higher before this; e.g., via compiler /D switch.
34*/
35#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
36#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000038
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000039#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000040#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000041#elif defined(HAVE_SYS_POLL_H)
42#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000043#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000044
Guido van Rossum37273171996-12-09 18:47:43 +000045#ifdef __sgi
46/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000047extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000048#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000052#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053
Guido van Rossum6f489d91996-06-28 20:15:15 +000054#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000055# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000057#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000059#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000060
Barry Warsawc1cb3601996-12-12 22:16:21 +000061/* list of Python objects and their file descriptor */
62typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 PyObject *obj; /* owned reference */
64 SOCKET fd;
65 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000066} pylist;
67
Barry Warsawc1cb3601996-12-12 22:16:21 +000068static void
Tim Peters4b046c22001-08-16 21:59:46 +000069reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000070{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020071 unsigned int i;
72 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +020073 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 }
75 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000076}
77
78
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000079/* returns -1 and sets the Python exception if an error occurred, otherwise
80 returns a number >= 0
81*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000082static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000083seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020086 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010087 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 PyObject* fast_seq = NULL;
89 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
92 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000094 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (!fast_seq)
96 return -1;
97
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010098 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 SOCKET v;
100
101 /* any intervening fileno() calls could decr this refcnt */
102 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200103 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 Py_INCREF(o);
106 v = PyObject_AsFileDescriptor( o );
107 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000108
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000109#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000111#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200112 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 PyErr_SetString(PyExc_ValueError,
114 "filedescriptor out of range in select()");
115 goto finally;
116 }
117 if (v > max)
118 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200123 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 PyErr_SetString(PyExc_ValueError,
125 "too many file descriptors in select()");
126 goto finally;
127 }
128 fd2obj[index].obj = o;
129 fd2obj[index].fd = v;
130 fd2obj[index].sentinel = 0;
131 fd2obj[++index].sentinel = -1;
132 }
133 Py_DECREF(fast_seq);
134 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135
136 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 Py_XDECREF(o);
138 Py_DECREF(fast_seq);
139 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000140}
141
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000142/* returns NULL and sets the Python exception if an error occurred */
143static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 int i, j, count=0;
147 PyObject *list, *o;
148 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
151 if (FD_ISSET(fd2obj[j].fd, set))
152 count++;
153 }
154 list = PyList_New(count);
155 if (!list)
156 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 i = 0;
159 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
160 fd = fd2obj[j].fd;
161 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 o = fd2obj[j].obj;
163 fd2obj[j].obj = NULL;
164 /* transfer ownership */
165 if (PyList_SetItem(list, i, o) < 0)
166 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 i++;
169 }
170 }
171 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 Py_DECREF(list);
174 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000175}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000176
Barry Warsawb44740f2001-08-16 16:52:59 +0000177#undef SELECT_USES_HEAP
178#if FD_SETSIZE > 1024
179#define SELECT_USES_HEAP
180#endif /* FD_SETSIZE > 1024 */
181
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000182static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000183select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000184{
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 /* XXX: All this should probably be implemented as follows:
189 * - find the highest descriptor we're interested in
190 * - add one
191 * - that's the size
192 * See: Stevens, APitUE, $12.5.1
193 */
194 pylist rfd2obj[FD_SETSIZE + 1];
195 pylist wfd2obj[FD_SETSIZE + 1];
196 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000197#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 PyObject *ifdlist, *ofdlist, *efdlist;
199 PyObject *ret = NULL;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200200 PyObject *timeout_obj = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 int imax, omax, emax, max;
204 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200205 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* convert arguments */
208 if (!PyArg_UnpackTuple(args, "select", 3, 4,
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200209 &ifdlist, &ofdlist, &efdlist, &timeout_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000211
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200212 if (timeout_obj == Py_None)
213 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200215 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100216 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200217 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
218 PyErr_SetString(PyExc_TypeError,
219 "timeout must be a float or None");
220 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100221 return NULL;
222 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100223
Pablo Galindo2c15b292017-10-17 15:14:41 +0100224 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100225 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100226 if (tv.tv_sec < 0) {
227 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 return NULL;
229 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 tvp = &tv;
231 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000232
Barry Warsawb44740f2001-08-16 16:52:59 +0000233#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 /* Allocate memory for the lists */
235 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
236 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
237 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
238 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
239 if (rfd2obj) PyMem_DEL(rfd2obj);
240 if (wfd2obj) PyMem_DEL(wfd2obj);
241 if (efd2obj) PyMem_DEL(efd2obj);
242 return PyErr_NoMemory();
243 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000244#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 /* Convert sequences to fd_sets, and get maximum fd number
247 * propagates the Python exception set in seq2set()
248 */
249 rfd2obj[0].sentinel = -1;
250 wfd2obj[0].sentinel = -1;
251 efd2obj[0].sentinel = -1;
252 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
253 goto finally;
254 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
255 goto finally;
256 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
257 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 max = imax;
260 if (omax > max) max = omax;
261 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000262
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200263 if (tvp)
264 deadline = _PyTime_GetMonotonicClock() + timeout;
265
266 do {
267 Py_BEGIN_ALLOW_THREADS
268 errno = 0;
269 n = select(max, &ifdset, &ofdset, &efdset, tvp);
270 Py_END_ALLOW_THREADS
271
272 if (errno != EINTR)
273 break;
274
275 /* select() was interrupted by a signal */
276 if (PyErr_CheckSignals())
277 goto finally;
278
279 if (tvp) {
280 timeout = deadline - _PyTime_GetMonotonicClock();
281 if (timeout < 0) {
282 n = 0;
283 break;
284 }
285 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200286 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200287 }
288 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000289
Thomas Heller106f4c72002-09-24 16:51:00 +0000290#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200292 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000294#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200296 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000298#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 else {
300 /* any of these three calls can raise an exception. it's more
301 convenient to test for this after all three calls... but
302 is that acceptable?
303 */
304 ifdlist = set2list(&ifdset, rfd2obj);
305 ofdlist = set2list(&ofdset, wfd2obj);
306 efdlist = set2list(&efdset, efd2obj);
307 if (PyErr_Occurred())
308 ret = NULL;
309 else
310 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000311
Victor Stinnerbbf8ce52013-07-09 00:49:03 +0200312 Py_XDECREF(ifdlist);
313 Py_XDECREF(ofdlist);
314 Py_XDECREF(efdlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 }
316
Barry Warsawc1cb3601996-12-12 22:16:21 +0000317 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 reap_obj(rfd2obj);
319 reap_obj(wfd2obj);
320 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000321#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 PyMem_DEL(rfd2obj);
323 PyMem_DEL(wfd2obj);
324 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000325#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000327}
328
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000329#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331 * poll() support
332 */
333
334typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 PyObject_HEAD
336 PyObject *dict;
337 int ufd_uptodate;
338 int ufd_len;
339 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300340 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000341} pollObject;
342
Jeremy Hylton938ace62002-07-17 16:30:39 +0000343static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346 contained within a pollObject. Return 1 on success, 0 on an error.
347*/
348
349static int
350update_ufd_array(pollObject *self)
351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 Py_ssize_t i, pos;
353 PyObject *key, *value;
354 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000355
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200356 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
358 if (self->ufds == NULL) {
359 self->ufds = old_ufds;
360 PyErr_NoMemory();
361 return 0;
362 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 i = pos = 0;
365 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200366 assert(i < self->ufd_len);
367 /* Never overflow */
368 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200369 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 i++;
371 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200372 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 self->ufd_uptodate = 1;
374 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000375}
376
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200377static int
378ushort_converter(PyObject *obj, void *ptr)
379{
380 unsigned long uval;
381
382 uval = PyLong_AsUnsignedLong(obj);
383 if (uval == (unsigned long)-1 && PyErr_Occurred())
384 return 0;
385 if (uval > USHRT_MAX) {
386 PyErr_SetString(PyExc_OverflowError,
387 "Python int too large for C unsigned short");
388 return 0;
389 }
390
391 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
392 return 1;
393}
394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000395PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000396"register(fd [, eventmask] ) -> None\n\n\
397Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000398fd -- either an integer, or an object with a fileno() method returning an\n\
399 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000400events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401
402static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200406 int fd;
407 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200410 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 fd = PyObject_AsFileDescriptor(o);
414 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 /* Add entry to the internal dictionary: the key is the
417 file descriptor, and the value is the event mask. */
418 key = PyLong_FromLong(fd);
419 if (key == NULL)
420 return NULL;
421 value = PyLong_FromLong(events);
422 if (value == NULL) {
423 Py_DECREF(key);
424 return NULL;
425 }
426 err = PyDict_SetItem(self->dict, key, value);
427 Py_DECREF(key);
428 Py_DECREF(value);
429 if (err < 0)
430 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 self->ufd_uptodate = 0;
433
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200434 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000437PyDoc_STRVAR(poll_modify_doc,
438"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000439Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000440fd -- either an integer, or an object with a fileno() method returning an\n\
441 int.\n\
442events -- an optional bitmask describing the type of events to check for");
443
444static PyObject *
445poll_modify(pollObject *self, PyObject *args)
446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200448 int fd;
449 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000451
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200452 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 fd = PyObject_AsFileDescriptor(o);
456 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 /* Modify registered fd */
459 key = PyLong_FromLong(fd);
460 if (key == NULL)
461 return NULL;
462 if (PyDict_GetItem(self->dict, key) == NULL) {
463 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200464 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200465 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return NULL;
467 }
468 value = PyLong_FromLong(events);
469 if (value == NULL) {
470 Py_DECREF(key);
471 return NULL;
472 }
473 err = PyDict_SetItem(self->dict, key, value);
474 Py_DECREF(key);
475 Py_DECREF(value);
476 if (err < 0)
477 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 self->ufd_uptodate = 0;
480
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200481 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000482}
483
484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000487Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
489static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 PyObject *key;
493 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 fd = PyObject_AsFileDescriptor( o );
496 if (fd == -1)
497 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 /* Check whether the fd is already in the array */
500 key = PyLong_FromLong(fd);
501 if (key == NULL)
502 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (PyDict_DelItem(self->dict, key) == -1) {
505 Py_DECREF(key);
506 /* This will simply raise the KeyError set by PyDict_DelItem
507 if the file descriptor isn't registered. */
508 return NULL;
509 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 Py_DECREF(key);
512 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000513
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200514 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515}
516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000517PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
519Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
522static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000524{
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200525 PyObject *result_list = NULL, *timeout_obj = NULL;
526 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200528 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200529 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000530
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200531 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 return NULL;
533 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000534
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200535 if (timeout_obj != NULL && timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200536 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100537 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200538 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
539 PyErr_SetString(PyExc_TypeError,
540 "timeout must be an integer or None");
541 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200543 }
544
Pablo Galindo2c15b292017-10-17 15:14:41 +0100545 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200546 if (ms < INT_MIN || ms > INT_MAX) {
547 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200549 }
550
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200551 if (timeout >= 0) {
552 deadline = _PyTime_GetMonotonicClock() + timeout;
553 }
554 }
555
556 /* On some OSes, typically BSD-based ones, the timeout parameter of the
557 poll() syscall, when negative, must be exactly INFTIM, where defined,
558 or -1. See issue 31334. */
559 if (ms < 0) {
560#ifdef INFTIM
561 ms = INFTIM;
562#else
563 ms = -1;
564#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000566
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300567 /* Avoid concurrent poll() invocation, issue 8865 */
568 if (self->poll_running) {
569 PyErr_SetString(PyExc_RuntimeError,
570 "concurrent poll() invocation");
571 return NULL;
572 }
573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 /* Ensure the ufd array is up to date */
575 if (!self->ufd_uptodate)
576 if (update_ufd_array(self) == 0)
577 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000578
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300579 self->poll_running = 1;
580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200582 async_err = 0;
583 do {
584 Py_BEGIN_ALLOW_THREADS
585 errno = 0;
586 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
587 Py_END_ALLOW_THREADS
588
589 if (errno != EINTR)
590 break;
591
592 /* poll() was interrupted by a signal */
593 if (PyErr_CheckSignals()) {
594 async_err = 1;
595 break;
596 }
597
598 if (timeout >= 0) {
599 timeout = deadline - _PyTime_GetMonotonicClock();
600 if (timeout < 0) {
601 poll_result = 0;
602 break;
603 }
604 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
605 /* retry poll() with the recomputed timeout */
606 }
607 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000608
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300609 self->poll_running = 0;
610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200612 if (!async_err)
613 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 return NULL;
615 }
616
617 /* build the result list */
618
619 result_list = PyList_New(poll_result);
620 if (!result_list)
621 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200623 for (i = 0, j = 0; j < poll_result; j++) {
624 /* skip to the next fired descriptor */
625 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 i++;
627 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200628 /* if we hit a NULL return, set value to NULL
629 and break out of loop; code at end will
630 clean up result_list */
631 value = PyTuple_New(2);
632 if (value == NULL)
633 goto error;
634 num = PyLong_FromLong(self->ufds[i].fd);
635 if (num == NULL) {
636 Py_DECREF(value);
637 goto error;
638 }
639 PyTuple_SET_ITEM(value, 0, num);
640
641 /* The &0xffff is a workaround for AIX. 'revents'
642 is a 16-bit short, and IBM assigned POLLNVAL
643 to be 0x8000, so the conversion to int results
644 in a negative number. See SF bug #923315. */
645 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
646 if (num == NULL) {
647 Py_DECREF(value);
648 goto error;
649 }
650 PyTuple_SET_ITEM(value, 1, num);
651 if ((PyList_SetItem(result_list, j, value)) == -1) {
652 Py_DECREF(value);
653 goto error;
654 }
655 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 }
657 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658
659 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 Py_DECREF(result_list);
661 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000662}
663
664static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 {"register", (PyCFunction)poll_register,
666 METH_VARARGS, poll_register_doc},
667 {"modify", (PyCFunction)poll_modify,
668 METH_VARARGS, poll_modify_doc},
669 {"unregister", (PyCFunction)poll_unregister,
670 METH_O, poll_unregister_doc},
671 {"poll", (PyCFunction)poll_poll,
672 METH_VARARGS, poll_poll_doc},
673 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000674};
675
676static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000677newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 pollObject *self;
680 self = PyObject_New(pollObject, &poll_Type);
681 if (self == NULL)
682 return NULL;
683 /* ufd_uptodate is a Boolean, denoting whether the
684 array pointed to by ufds matches the contents of the dictionary. */
685 self->ufd_uptodate = 0;
686 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300687 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 self->dict = PyDict_New();
689 if (self->dict == NULL) {
690 Py_DECREF(self);
691 return NULL;
692 }
693 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000694}
695
696static void
697poll_dealloc(pollObject *self)
698{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 if (self->ufds != NULL)
700 PyMem_DEL(self->ufds);
701 Py_XDECREF(self->dict);
702 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000703}
704
Tim Peters0c322792002-07-17 16:49:03 +0000705static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 /* The ob_type field must be initialized in the module init function
707 * to be portable to Windows without using C++. */
708 PyVarObject_HEAD_INIT(NULL, 0)
709 "select.poll", /*tp_name*/
710 sizeof(pollObject), /*tp_basicsize*/
711 0, /*tp_itemsize*/
712 /* methods */
713 (destructor)poll_dealloc, /*tp_dealloc*/
714 0, /*tp_print*/
715 0, /*tp_getattr*/
716 0, /*tp_setattr*/
717 0, /*tp_reserved*/
718 0, /*tp_repr*/
719 0, /*tp_as_number*/
720 0, /*tp_as_sequence*/
721 0, /*tp_as_mapping*/
722 0, /*tp_hash*/
723 0, /*tp_call*/
724 0, /*tp_str*/
725 0, /*tp_getattro*/
726 0, /*tp_setattro*/
727 0, /*tp_as_buffer*/
728 Py_TPFLAGS_DEFAULT, /*tp_flags*/
729 0, /*tp_doc*/
730 0, /*tp_traverse*/
731 0, /*tp_clear*/
732 0, /*tp_richcompare*/
733 0, /*tp_weaklistoffset*/
734 0, /*tp_iter*/
735 0, /*tp_iternext*/
736 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000737};
738
Jesus Cead8b9ae62011-11-14 19:07:41 +0100739#ifdef HAVE_SYS_DEVPOLL_H
740typedef struct {
741 PyObject_HEAD
742 int fd_devpoll;
743 int max_n_fds;
744 int n_fds;
745 struct pollfd *fds;
746} devpollObject;
747
748static PyTypeObject devpoll_Type;
749
Victor Stinner13423c32013-08-22 00:19:50 +0200750static PyObject *
751devpoll_err_closed(void)
752{
753 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
754 return NULL;
755}
756
Jesus Cead8b9ae62011-11-14 19:07:41 +0100757static int devpoll_flush(devpollObject *self)
758{
759 int size, n;
760
761 if (!self->n_fds) return 0;
762
763 size = sizeof(struct pollfd)*self->n_fds;
764 self->n_fds = 0;
765
Victor Stinner54799672015-03-19 23:33:09 +0100766 n = _Py_write(self->fd_devpoll, self->fds, size);
767 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100768 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100769
Jesus Cead8b9ae62011-11-14 19:07:41 +0100770 if (n < size) {
771 /*
772 ** Data writed to /dev/poll is a binary data structure. It is not
773 ** clear what to do if a partial write occurred. For now, raise
774 ** an exception and see if we actually found this problem in
775 ** the wild.
776 ** See http://bugs.python.org/issue6397.
777 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300778 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100779 "Please, report at http://bugs.python.org/. "
780 "Data to report: Size tried: %d, actual size written: %d.",
781 size, n);
782 return -1;
783 }
784 return 0;
785}
786
787static PyObject *
788internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
789{
790 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200791 int fd;
792 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100793
Victor Stinner13423c32013-08-22 00:19:50 +0200794 if (self->fd_devpoll < 0)
795 return devpoll_err_closed();
796
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200797 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100798 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100799
800 fd = PyObject_AsFileDescriptor(o);
801 if (fd == -1) return NULL;
802
803 if (remove) {
804 self->fds[self->n_fds].fd = fd;
805 self->fds[self->n_fds].events = POLLREMOVE;
806
807 if (++self->n_fds == self->max_n_fds) {
808 if (devpoll_flush(self))
809 return NULL;
810 }
811 }
812
813 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200814 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100815
816 if (++self->n_fds == self->max_n_fds) {
817 if (devpoll_flush(self))
818 return NULL;
819 }
820
821 Py_RETURN_NONE;
822}
823
824PyDoc_STRVAR(devpoll_register_doc,
825"register(fd [, eventmask] ) -> None\n\n\
826Register a file descriptor with the polling object.\n\
827fd -- either an integer, or an object with a fileno() method returning an\n\
828 int.\n\
829events -- an optional bitmask describing the type of events to check for");
830
831static PyObject *
832devpoll_register(devpollObject *self, PyObject *args)
833{
834 return internal_devpoll_register(self, args, 0);
835}
836
837PyDoc_STRVAR(devpoll_modify_doc,
838"modify(fd[, eventmask]) -> None\n\n\
839Modify a possible already registered file descriptor.\n\
840fd -- either an integer, or an object with a fileno() method returning an\n\
841 int.\n\
842events -- an optional bitmask describing the type of events to check for");
843
844static PyObject *
845devpoll_modify(devpollObject *self, PyObject *args)
846{
847 return internal_devpoll_register(self, args, 1);
848}
849
850
851PyDoc_STRVAR(devpoll_unregister_doc,
852"unregister(fd) -> None\n\n\
853Remove a file descriptor being tracked by the polling object.");
854
855static PyObject *
856devpoll_unregister(devpollObject *self, PyObject *o)
857{
858 int fd;
859
Victor Stinner13423c32013-08-22 00:19:50 +0200860 if (self->fd_devpoll < 0)
861 return devpoll_err_closed();
862
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863 fd = PyObject_AsFileDescriptor( o );
864 if (fd == -1)
865 return NULL;
866
867 self->fds[self->n_fds].fd = fd;
868 self->fds[self->n_fds].events = POLLREMOVE;
869
870 if (++self->n_fds == self->max_n_fds) {
871 if (devpoll_flush(self))
872 return NULL;
873 }
874
875 Py_RETURN_NONE;
876}
877
878PyDoc_STRVAR(devpoll_poll_doc,
879"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
880Polls the set of registered file descriptors, returning a list containing \n\
881any descriptors that have events or errors to report.");
882
883static PyObject *
884devpoll_poll(devpollObject *self, PyObject *args)
885{
886 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200887 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100888 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100889 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200890 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100891
Victor Stinner13423c32013-08-22 00:19:50 +0200892 if (self->fd_devpoll < 0)
893 return devpoll_err_closed();
894
Victor Stinner45ca48b2015-03-31 12:10:33 +0200895 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100896 return NULL;
897 }
898
899 /* Check values for timeout */
Victor Stinner45ca48b2015-03-31 12:10:33 +0200900 if (timeout_obj == NULL || timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100901 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200902 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100903 }
904 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200905 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100906 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200907 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
908 PyErr_SetString(PyExc_TypeError,
909 "timeout must be an integer or None");
910 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100911 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200912 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100913
Pablo Galindo2c15b292017-10-17 15:14:41 +0100914 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200915 if (ms < -1 || ms > INT_MAX) {
916 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
917 return NULL;
918 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919 }
920
921 if (devpoll_flush(self))
922 return NULL;
923
924 dvp.dp_fds = self->fds;
925 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200926 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100927
Victor Stinner45ca48b2015-03-31 12:10:33 +0200928 if (timeout >= 0)
929 deadline = _PyTime_GetMonotonicClock() + timeout;
930
931 do {
932 /* call devpoll() */
933 Py_BEGIN_ALLOW_THREADS
934 errno = 0;
935 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
936 Py_END_ALLOW_THREADS
937
938 if (errno != EINTR)
939 break;
940
941 /* devpoll() was interrupted by a signal */
942 if (PyErr_CheckSignals())
943 return NULL;
944
945 if (timeout >= 0) {
946 timeout = deadline - _PyTime_GetMonotonicClock();
947 if (timeout < 0) {
948 poll_result = 0;
949 break;
950 }
951 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
952 dvp.dp_timeout = (int)ms;
953 /* retry devpoll() with the recomputed timeout */
954 }
955 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100956
957 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300958 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100959 return NULL;
960 }
961
962 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100963 result_list = PyList_New(poll_result);
964 if (!result_list)
965 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200966
967 for (i = 0; i < poll_result; i++) {
968 num1 = PyLong_FromLong(self->fds[i].fd);
969 num2 = PyLong_FromLong(self->fds[i].revents);
970 if ((num1 == NULL) || (num2 == NULL)) {
971 Py_XDECREF(num1);
972 Py_XDECREF(num2);
973 goto error;
974 }
975 value = PyTuple_Pack(2, num1, num2);
976 Py_DECREF(num1);
977 Py_DECREF(num2);
978 if (value == NULL)
979 goto error;
980 if ((PyList_SetItem(result_list, i, value)) == -1) {
981 Py_DECREF(value);
982 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100983 }
984 }
985
986 return result_list;
987
988 error:
989 Py_DECREF(result_list);
990 return NULL;
991}
992
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100993static int
994devpoll_internal_close(devpollObject *self)
995{
996 int save_errno = 0;
997 if (self->fd_devpoll >= 0) {
998 int fd = self->fd_devpoll;
999 self->fd_devpoll = -1;
1000 Py_BEGIN_ALLOW_THREADS
1001 if (close(fd) < 0)
1002 save_errno = errno;
1003 Py_END_ALLOW_THREADS
1004 }
1005 return save_errno;
1006}
1007
Victor Stinner13423c32013-08-22 00:19:50 +02001008static PyObject*
1009devpoll_close(devpollObject *self)
1010{
1011 errno = devpoll_internal_close(self);
1012 if (errno < 0) {
1013 PyErr_SetFromErrno(PyExc_OSError);
1014 return NULL;
1015 }
1016 Py_RETURN_NONE;
1017}
1018
1019PyDoc_STRVAR(devpoll_close_doc,
1020"close() -> None\n\
1021\n\
1022Close the devpoll file descriptor. Further operations on the devpoll\n\
1023object will raise an exception.");
1024
1025static PyObject*
1026devpoll_get_closed(devpollObject *self)
1027{
1028 if (self->fd_devpoll < 0)
1029 Py_RETURN_TRUE;
1030 else
1031 Py_RETURN_FALSE;
1032}
1033
1034static PyObject*
1035devpoll_fileno(devpollObject *self)
1036{
1037 if (self->fd_devpoll < 0)
1038 return devpoll_err_closed();
1039 return PyLong_FromLong(self->fd_devpoll);
1040}
1041
1042PyDoc_STRVAR(devpoll_fileno_doc,
1043"fileno() -> int\n\
1044\n\
1045Return the file descriptor.");
1046
Jesus Cead8b9ae62011-11-14 19:07:41 +01001047static PyMethodDef devpoll_methods[] = {
1048 {"register", (PyCFunction)devpoll_register,
1049 METH_VARARGS, devpoll_register_doc},
1050 {"modify", (PyCFunction)devpoll_modify,
1051 METH_VARARGS, devpoll_modify_doc},
1052 {"unregister", (PyCFunction)devpoll_unregister,
1053 METH_O, devpoll_unregister_doc},
1054 {"poll", (PyCFunction)devpoll_poll,
1055 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +02001056 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
1057 devpoll_close_doc},
1058 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
1059 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +01001060 {NULL, NULL} /* sentinel */
1061};
1062
Victor Stinner13423c32013-08-22 00:19:50 +02001063static PyGetSetDef devpoll_getsetlist[] = {
1064 {"closed", (getter)devpoll_get_closed, NULL,
1065 "True if the devpoll object is closed"},
1066 {0},
1067};
1068
Jesus Cead8b9ae62011-11-14 19:07:41 +01001069static devpollObject *
1070newDevPollObject(void)
1071{
1072 devpollObject *self;
1073 int fd_devpoll, limit_result;
1074 struct pollfd *fds;
1075 struct rlimit limit;
1076
Jesus Cead8b9ae62011-11-14 19:07:41 +01001077 /*
1078 ** If we try to process more that getrlimit()
1079 ** fds, the kernel will give an error, so
1080 ** we set the limit here. It is a dynamic
1081 ** value, because we can change rlimit() anytime.
1082 */
1083 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001084 if (limit_result == -1) {
1085 PyErr_SetFromErrno(PyExc_OSError);
1086 return NULL;
1087 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001088
1089 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1090 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001091 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001092
1093 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1094 if (fds == NULL) {
1095 close(fd_devpoll);
1096 PyErr_NoMemory();
1097 return NULL;
1098 }
1099
1100 self = PyObject_New(devpollObject, &devpoll_Type);
1101 if (self == NULL) {
1102 close(fd_devpoll);
1103 PyMem_DEL(fds);
1104 return NULL;
1105 }
1106 self->fd_devpoll = fd_devpoll;
1107 self->max_n_fds = limit.rlim_cur;
1108 self->n_fds = 0;
1109 self->fds = fds;
1110
1111 return self;
1112}
1113
1114static void
1115devpoll_dealloc(devpollObject *self)
1116{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001117 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001118 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001119 PyObject_Del(self);
1120}
1121
1122static PyTypeObject devpoll_Type = {
1123 /* The ob_type field must be initialized in the module init function
1124 * to be portable to Windows without using C++. */
1125 PyVarObject_HEAD_INIT(NULL, 0)
1126 "select.devpoll", /*tp_name*/
1127 sizeof(devpollObject), /*tp_basicsize*/
1128 0, /*tp_itemsize*/
1129 /* methods */
1130 (destructor)devpoll_dealloc, /*tp_dealloc*/
1131 0, /*tp_print*/
1132 0, /*tp_getattr*/
1133 0, /*tp_setattr*/
1134 0, /*tp_reserved*/
1135 0, /*tp_repr*/
1136 0, /*tp_as_number*/
1137 0, /*tp_as_sequence*/
1138 0, /*tp_as_mapping*/
1139 0, /*tp_hash*/
1140 0, /*tp_call*/
1141 0, /*tp_str*/
1142 0, /*tp_getattro*/
1143 0, /*tp_setattro*/
1144 0, /*tp_as_buffer*/
1145 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1146 0, /*tp_doc*/
1147 0, /*tp_traverse*/
1148 0, /*tp_clear*/
1149 0, /*tp_richcompare*/
1150 0, /*tp_weaklistoffset*/
1151 0, /*tp_iter*/
1152 0, /*tp_iternext*/
1153 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001154 0, /* tp_members */
1155 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001156};
1157#endif /* HAVE_SYS_DEVPOLL_H */
1158
1159
1160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001161PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001162"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001163unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001164
1165static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001166select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001169}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001170
Jesus Cead8b9ae62011-11-14 19:07:41 +01001171#ifdef HAVE_SYS_DEVPOLL_H
1172PyDoc_STRVAR(devpoll_doc,
1173"Returns a polling object, which supports registering and\n\
1174unregistering file descriptors, and then polling them for I/O events.");
1175
1176static PyObject *
1177select_devpoll(PyObject *self, PyObject *unused)
1178{
1179 return (PyObject *)newDevPollObject();
1180}
1181#endif
1182
1183
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001186 * On some systems poll() sets errno on invalid file descriptors. We test
1187 * for this at runtime because this bug may be fixed or introduced between
1188 * OS releases.
1189 */
1190static int select_have_broken_poll(void)
1191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 int poll_test;
1193 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 /* Create a file descriptor to make invalid */
1198 if (pipe(filedes) < 0) {
1199 return 1;
1200 }
1201 poll_struct.fd = filedes[0];
1202 close(filedes[0]);
1203 close(filedes[1]);
1204 poll_test = poll(&poll_struct, 1, 0);
1205 if (poll_test < 0) {
1206 return 1;
1207 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1208 return 1;
1209 }
1210 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211}
1212#endif /* __APPLE__ */
1213
1214#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001215
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216#ifdef HAVE_EPOLL
1217/* **************************************************************************
1218 * epoll interface for Linux 2.6
1219 *
1220 * Written by Christian Heimes
1221 * Inspired by Twisted's _epoll.pyx and select.poll()
1222 */
1223
1224#ifdef HAVE_SYS_EPOLL_H
1225#include <sys/epoll.h>
1226#endif
1227
1228typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001230 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231} pyEpoll_Object;
1232
1233static PyTypeObject pyEpoll_Type;
1234#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1235
1236static PyObject *
1237pyepoll_err_closed(void)
1238{
Victor Stinner13423c32013-08-22 00:19:50 +02001239 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001241}
1242
1243static int
1244pyepoll_internal_close(pyEpoll_Object *self)
1245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 int save_errno = 0;
1247 if (self->epfd >= 0) {
1248 int epfd = self->epfd;
1249 self->epfd = -1;
1250 Py_BEGIN_ALLOW_THREADS
1251 if (close(epfd) < 0)
1252 save_errno = errno;
1253 Py_END_ALLOW_THREADS
1254 }
1255 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256}
1257
1258static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001259newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 assert(type != NULL && type->tp_alloc != NULL);
1264 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1265 if (self == NULL)
1266 return NULL;
1267
1268 if (fd == -1) {
1269 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001270#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001271 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1272#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001273 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001274#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_END_ALLOW_THREADS
1276 }
1277 else {
1278 self->epfd = fd;
1279 }
1280 if (self->epfd < 0) {
1281 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001282 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 return NULL;
1284 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001285
1286#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001287 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001288 Py_DECREF(self);
1289 return NULL;
1290 }
1291#endif
1292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001294}
1295
1296
1297static PyObject *
1298pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1299{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001300 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001301 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001302
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001303 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1304 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001306 if (sizehint < 0) {
1307 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1308 return NULL;
1309 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001310
1311#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001312 if (flags && flags != EPOLL_CLOEXEC) {
1313 PyErr_SetString(PyExc_OSError, "invalid flags");
1314 return NULL;
1315 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001316#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001317
Berker Peksage2197d12016-09-26 23:30:41 +03001318 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001319}
1320
1321
1322static void
1323pyepoll_dealloc(pyEpoll_Object *self)
1324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 (void)pyepoll_internal_close(self);
1326 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001327}
1328
1329static PyObject*
1330pyepoll_close(pyEpoll_Object *self)
1331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 errno = pyepoll_internal_close(self);
1333 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001334 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 return NULL;
1336 }
1337 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001338}
1339
1340PyDoc_STRVAR(pyepoll_close_doc,
1341"close() -> None\n\
1342\n\
1343Close the epoll control file descriptor. Further operations on the epoll\n\
1344object will raise an exception.");
1345
1346static PyObject*
1347pyepoll_get_closed(pyEpoll_Object *self)
1348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 if (self->epfd < 0)
1350 Py_RETURN_TRUE;
1351 else
1352 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001353}
1354
1355static PyObject*
1356pyepoll_fileno(pyEpoll_Object *self)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 if (self->epfd < 0)
1359 return pyepoll_err_closed();
1360 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361}
1362
1363PyDoc_STRVAR(pyepoll_fileno_doc,
1364"fileno() -> int\n\
1365\n\
1366Return the epoll control file descriptor.");
1367
1368static PyObject*
1369pyepoll_fromfd(PyObject *cls, PyObject *args)
1370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1374 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001375
Berker Peksage2197d12016-09-26 23:30:41 +03001376 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377}
1378
1379PyDoc_STRVAR(pyepoll_fromfd_doc,
1380"fromfd(fd) -> epoll\n\
1381\n\
1382Create an epoll object from a given control fd.");
1383
1384static PyObject *
1385pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 struct epoll_event ev;
1388 int result;
1389 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (epfd < 0)
1392 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 fd = PyObject_AsFileDescriptor(pfd);
1395 if (fd == -1) {
1396 return NULL;
1397 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001398
Guido van Rossumee07b942013-12-06 17:46:22 -08001399 switch (op) {
1400 case EPOLL_CTL_ADD:
1401 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 ev.events = events;
1403 ev.data.fd = fd;
1404 Py_BEGIN_ALLOW_THREADS
1405 result = epoll_ctl(epfd, op, fd, &ev);
1406 Py_END_ALLOW_THREADS
1407 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001408 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1410 * operation required a non-NULL pointer in event, even
1411 * though this argument is ignored. */
1412 Py_BEGIN_ALLOW_THREADS
1413 result = epoll_ctl(epfd, op, fd, &ev);
1414 if (errno == EBADF) {
1415 /* fd already closed */
1416 result = 0;
1417 errno = 0;
1418 }
1419 Py_END_ALLOW_THREADS
1420 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001421 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 result = -1;
1423 errno = EINVAL;
1424 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001427 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 return NULL;
1429 }
1430 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001431}
1432
1433static PyObject *
1434pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 PyObject *pfd;
1437 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1438 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1441 &pfd, &events)) {
1442 return NULL;
1443 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446}
1447
1448PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001449"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001450\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001451Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001452fd is the target file descriptor of the operation.\n\
1453events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001454is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455\n\
1456The epoll interface supports all file descriptors that support poll.");
1457
1458static PyObject *
1459pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 PyObject *pfd;
1462 unsigned int events;
1463 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1466 &pfd, &events)) {
1467 return NULL;
1468 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471}
1472
1473PyDoc_STRVAR(pyepoll_modify_doc,
1474"modify(fd, eventmask) -> None\n\
1475\n\
1476fd is the target file descriptor of the operation\n\
1477events is a bit set composed of the various EPOLL constants");
1478
1479static PyObject *
1480pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 PyObject *pfd;
1483 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1486 &pfd)) {
1487 return NULL;
1488 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001491}
1492
1493PyDoc_STRVAR(pyepoll_unregister_doc,
1494"unregister(fd) -> None\n\
1495\n\
1496fd is the target file descriptor of the operation.");
1497
1498static PyObject *
1499pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1500{
Victor Stinner41eba222015-03-30 21:59:21 +02001501 static char *kwlist[] = {"timeout", "maxevents", NULL};
1502 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 int maxevents = -1;
1504 int nfds, i;
1505 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001506 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001507 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 if (self->epfd < 0)
1510 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511
Victor Stinner41eba222015-03-30 21:59:21 +02001512 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1513 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 return NULL;
1515 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001516
Victor Stinner41eba222015-03-30 21:59:21 +02001517 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001519 ms = -1;
1520 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 }
1522 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001523 /* epoll_wait() has a resolution of 1 millisecond, round towards
1524 infinity to wait at least timeout seconds. */
1525 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001526 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001527 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1528 PyErr_SetString(PyExc_TypeError,
1529 "timeout must be an integer or None");
1530 }
1531 return NULL;
1532 }
1533
1534 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1535 if (ms < INT_MIN || ms > INT_MAX) {
1536 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1537 return NULL;
1538 }
1539
1540 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001544 maxevents = FD_SETSIZE-1;
1545 }
1546 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 PyErr_Format(PyExc_ValueError,
1548 "maxevents must be greater than 0, got %d",
1549 maxevents);
1550 return NULL;
1551 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001553 evs = PyMem_New(struct epoll_event, maxevents);
1554 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001555 PyErr_NoMemory();
1556 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001558
Victor Stinner41eba222015-03-30 21:59:21 +02001559 do {
1560 Py_BEGIN_ALLOW_THREADS
1561 errno = 0;
1562 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1563 Py_END_ALLOW_THREADS
1564
1565 if (errno != EINTR)
1566 break;
1567
1568 /* poll() was interrupted by a signal */
1569 if (PyErr_CheckSignals())
1570 goto error;
1571
1572 if (timeout >= 0) {
1573 timeout = deadline - _PyTime_GetMonotonicClock();
1574 if (timeout < 0) {
1575 nfds = 0;
1576 break;
1577 }
1578 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1579 /* retry epoll_wait() with the recomputed timeout */
1580 }
1581 } while(1);
1582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001584 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 goto error;
1586 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 elist = PyList_New(nfds);
1589 if (elist == NULL) {
1590 goto error;
1591 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001594 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (etuple == NULL) {
1596 Py_CLEAR(elist);
1597 goto error;
1598 }
1599 PyList_SET_ITEM(elist, i, etuple);
1600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Christian Heimesf6cd9672008-03-26 13:45:42 +00001602 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001603 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605}
1606
1607PyDoc_STRVAR(pyepoll_poll_doc,
1608"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1609\n\
1610Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1611in seconds (as float). -1 makes poll wait indefinitely.\n\
1612Up to maxevents are returned to the caller.");
1613
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001614static PyObject *
1615pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1616{
1617 if (self->epfd < 0)
1618 return pyepoll_err_closed();
1619
1620 Py_INCREF(self);
1621 return (PyObject *)self;
1622}
1623
1624static PyObject *
1625pyepoll_exit(PyObject *self, PyObject *args)
1626{
1627 _Py_IDENTIFIER(close);
1628
1629 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1630}
1631
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 {"fromfd", (PyCFunction)pyepoll_fromfd,
1634 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1635 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1636 pyepoll_close_doc},
1637 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1638 pyepoll_fileno_doc},
1639 {"modify", (PyCFunction)pyepoll_modify,
1640 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1641 {"register", (PyCFunction)pyepoll_register,
1642 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1643 {"unregister", (PyCFunction)pyepoll_unregister,
1644 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1645 {"poll", (PyCFunction)pyepoll_poll,
1646 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001647 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1648 NULL},
1649 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1650 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652};
1653
1654static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 {"closed", (getter)pyepoll_get_closed, NULL,
1656 "True if the epoll handler is closed"},
1657 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001658};
1659
1660PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001661"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001662\n\
1663Returns an epolling object\n\
1664\n\
1665sizehint must be a positive integer or -1 for the default size. The\n\
1666sizehint is used to optimize internal data structures. It doesn't limit\n\
1667the maximum number of monitored events.");
1668
1669static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 PyVarObject_HEAD_INIT(NULL, 0)
1671 "select.epoll", /* tp_name */
1672 sizeof(pyEpoll_Object), /* tp_basicsize */
1673 0, /* tp_itemsize */
1674 (destructor)pyepoll_dealloc, /* tp_dealloc */
1675 0, /* tp_print */
1676 0, /* tp_getattr */
1677 0, /* tp_setattr */
1678 0, /* tp_reserved */
1679 0, /* tp_repr */
1680 0, /* tp_as_number */
1681 0, /* tp_as_sequence */
1682 0, /* tp_as_mapping */
1683 0, /* tp_hash */
1684 0, /* tp_call */
1685 0, /* tp_str */
1686 PyObject_GenericGetAttr, /* tp_getattro */
1687 0, /* tp_setattro */
1688 0, /* tp_as_buffer */
1689 Py_TPFLAGS_DEFAULT, /* tp_flags */
1690 pyepoll_doc, /* tp_doc */
1691 0, /* tp_traverse */
1692 0, /* tp_clear */
1693 0, /* tp_richcompare */
1694 0, /* tp_weaklistoffset */
1695 0, /* tp_iter */
1696 0, /* tp_iternext */
1697 pyepoll_methods, /* tp_methods */
1698 0, /* tp_members */
1699 pyepoll_getsetlist, /* tp_getset */
1700 0, /* tp_base */
1701 0, /* tp_dict */
1702 0, /* tp_descr_get */
1703 0, /* tp_descr_set */
1704 0, /* tp_dictoffset */
1705 0, /* tp_init */
1706 0, /* tp_alloc */
1707 pyepoll_new, /* tp_new */
1708 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001709};
1710
1711#endif /* HAVE_EPOLL */
1712
1713#ifdef HAVE_KQUEUE
1714/* **************************************************************************
1715 * kqueue interface for BSD
1716 *
1717 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1718 * All rights reserved.
1719 *
1720 * Redistribution and use in source and binary forms, with or without
1721 * modification, are permitted provided that the following conditions
1722 * are met:
1723 * 1. Redistributions of source code must retain the above copyright
1724 * notice, this list of conditions and the following disclaimer.
1725 * 2. Redistributions in binary form must reproduce the above copyright
1726 * notice, this list of conditions and the following disclaimer in the
1727 * documentation and/or other materials provided with the distribution.
1728 *
1729 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1730 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1731 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1732 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1733 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1734 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1735 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1736 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1737 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1738 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1739 * SUCH DAMAGE.
1740 */
1741
1742#ifdef HAVE_SYS_EVENT_H
1743#include <sys/event.h>
1744#endif
1745
1746PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001747"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001748\n\
1749This object is the equivalent of the struct kevent for the C API.\n\
1750\n\
1751See the kqueue manpage for more detailed information about the meaning\n\
1752of the arguments.\n\
1753\n\
1754One minor note: while you might hope that udata could store a\n\
1755reference to a python object, it cannot, because it is impossible to\n\
1756keep a proper reference count of the object once it's passed into the\n\
1757kernel. Therefore, I have restricted it to only storing an integer. I\n\
1758recommend ignoring it and simply using the 'ident' field to key off\n\
1759of. You could also set up a dictionary on the python side to store a\n\
1760udata->object mapping.");
1761
1762typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 PyObject_HEAD
1764 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001765} kqueue_event_Object;
1766
1767static PyTypeObject kqueue_event_Type;
1768
1769#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1770
1771typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 PyObject_HEAD
1773 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001774} kqueue_queue_Object;
1775
1776static PyTypeObject kqueue_queue_Type;
1777
1778#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1779
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001780#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1781# error uintptr_t does not match void *!
1782#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1783# define T_UINTPTRT T_ULONGLONG
1784# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001785# define UINTPTRT_FMT_UNIT "K"
1786# define INTPTRT_FMT_UNIT "L"
1787#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1788# define T_UINTPTRT T_ULONG
1789# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001790# define UINTPTRT_FMT_UNIT "k"
1791# define INTPTRT_FMT_UNIT "l"
1792#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1793# define T_UINTPTRT T_UINT
1794# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001795# define UINTPTRT_FMT_UNIT "I"
1796# define INTPTRT_FMT_UNIT "i"
1797#else
1798# error uintptr_t does not match int, long, or long long!
1799#endif
1800
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001801#if SIZEOF_LONG_LONG == 8
1802# define T_INT64 T_LONGLONG
1803# define INT64_FMT_UNIT "L"
1804#elif SIZEOF_LONG == 8
1805# define T_INT64 T_LONG
1806# define INT64_FMT_UNIT "l"
1807#elif SIZEOF_INT == 8
1808# define T_INT64 T_INT
1809# define INT64_FMT_UNIT "i"
1810#else
1811# define INT64_FMT_UNIT "_"
1812#endif
1813
1814#if SIZEOF_LONG_LONG == 4
1815# define T_UINT32 T_ULONGLONG
1816# define UINT32_FMT_UNIT "K"
1817#elif SIZEOF_LONG == 4
1818# define T_UINT32 T_ULONG
1819# define UINT32_FMT_UNIT "k"
1820#elif SIZEOF_INT == 4
1821# define T_UINT32 T_UINT
1822# define UINT32_FMT_UNIT "I"
1823#else
1824# define UINT32_FMT_UNIT "_"
1825#endif
1826
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001827/*
1828 * kevent is not standard and its members vary across BSDs.
1829 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001830#ifdef __NetBSD__
1831# define FILTER_TYPE T_UINT32
1832# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1833# define FLAGS_TYPE T_UINT32
1834# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1835# define FFLAGS_TYPE T_UINT32
1836# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001837#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001838# define FILTER_TYPE T_SHORT
1839# define FILTER_FMT_UNIT "h"
1840# define FLAGS_TYPE T_USHORT
1841# define FLAGS_FMT_UNIT "H"
1842# define FFLAGS_TYPE T_UINT
1843# define FFLAGS_FMT_UNIT "I"
1844#endif
1845
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001846#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001847# define DATA_TYPE T_INT64
1848# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001849#else
1850# define DATA_TYPE T_INTPTRT
1851# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001852#endif
1853
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001854/* Unfortunately, we can't store python objects in udata, because
1855 * kevents in the kernel can be removed without warning, which would
1856 * forever lose the refcount on the object stored with it.
1857 */
1858
1859#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1860static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001861 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1862 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1863 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001865 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1867 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868};
1869#undef KQ_OFF
1870
1871static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001872
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873kqueue_event_repr(kqueue_event_Object *s)
1874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 char buf[1024];
1876 PyOS_snprintf(
1877 buf, sizeof(buf),
1878 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001879 "data=0x%llx udata=%p>",
1880 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1881 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883}
1884
1885static int
1886kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 PyObject *pfd;
1889 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1890 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001891 static const char fmt[] = "O|"
1892 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1893 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1898 &pfd, &(self->e.filter), &(self->e.flags),
1899 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1900 return -1;
1901 }
1902
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001903 if (PyLong_Check(pfd)) {
1904 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 }
1906 else {
1907 self->e.ident = PyObject_AsFileDescriptor(pfd);
1908 }
1909 if (PyErr_Occurred()) {
1910 return -1;
1911 }
1912 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001913}
1914
1915static PyObject *
1916kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001918{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001919 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001922 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001924
1925#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1926 result = CMP(s->e.ident, o->e.ident)
1927 : CMP(s->e.filter, o->e.filter)
1928 : CMP(s->e.flags, o->e.flags)
1929 : CMP(s->e.fflags, o->e.fflags)
1930 : CMP(s->e.data, o->e.data)
1931 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1932 : 0;
1933#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001934
stratakise8b19652017-11-02 11:32:54 +01001935 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001936}
1937
1938static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 PyVarObject_HEAD_INIT(NULL, 0)
1940 "select.kevent", /* tp_name */
1941 sizeof(kqueue_event_Object), /* tp_basicsize */
1942 0, /* tp_itemsize */
1943 0, /* tp_dealloc */
1944 0, /* tp_print */
1945 0, /* tp_getattr */
1946 0, /* tp_setattr */
1947 0, /* tp_reserved */
1948 (reprfunc)kqueue_event_repr, /* tp_repr */
1949 0, /* tp_as_number */
1950 0, /* tp_as_sequence */
1951 0, /* tp_as_mapping */
1952 0, /* tp_hash */
1953 0, /* tp_call */
1954 0, /* tp_str */
1955 0, /* tp_getattro */
1956 0, /* tp_setattro */
1957 0, /* tp_as_buffer */
1958 Py_TPFLAGS_DEFAULT, /* tp_flags */
1959 kqueue_event_doc, /* tp_doc */
1960 0, /* tp_traverse */
1961 0, /* tp_clear */
1962 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1963 0, /* tp_weaklistoffset */
1964 0, /* tp_iter */
1965 0, /* tp_iternext */
1966 0, /* tp_methods */
1967 kqueue_event_members, /* tp_members */
1968 0, /* tp_getset */
1969 0, /* tp_base */
1970 0, /* tp_dict */
1971 0, /* tp_descr_get */
1972 0, /* tp_descr_set */
1973 0, /* tp_dictoffset */
1974 (initproc)kqueue_event_init, /* tp_init */
1975 0, /* tp_alloc */
1976 0, /* tp_new */
1977 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001978};
1979
1980static PyObject *
1981kqueue_queue_err_closed(void)
1982{
Victor Stinner13423c32013-08-22 00:19:50 +02001983 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001985}
1986
1987static int
1988kqueue_queue_internal_close(kqueue_queue_Object *self)
1989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 int save_errno = 0;
1991 if (self->kqfd >= 0) {
1992 int kqfd = self->kqfd;
1993 self->kqfd = -1;
1994 Py_BEGIN_ALLOW_THREADS
1995 if (close(kqfd) < 0)
1996 save_errno = errno;
1997 Py_END_ALLOW_THREADS
1998 }
1999 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002000}
2001
2002static PyObject *
2003newKqueue_Object(PyTypeObject *type, SOCKET fd)
2004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 kqueue_queue_Object *self;
2006 assert(type != NULL && type->tp_alloc != NULL);
2007 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
2008 if (self == NULL) {
2009 return NULL;
2010 }
2011
2012 if (fd == -1) {
2013 Py_BEGIN_ALLOW_THREADS
2014 self->kqfd = kqueue();
2015 Py_END_ALLOW_THREADS
2016 }
2017 else {
2018 self->kqfd = fd;
2019 }
2020 if (self->kqfd < 0) {
2021 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002022 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 return NULL;
2024 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002025
2026 if (fd == -1) {
2027 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2028 Py_DECREF(self);
2029 return NULL;
2030 }
2031 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033}
2034
2035static PyObject *
2036kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2037{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002038 if (PyTuple_GET_SIZE(args) ||
2039 (kwds != NULL && PyDict_GET_SIZE(kwds))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 PyErr_SetString(PyExc_ValueError,
2041 "select.kqueue doesn't accept arguments");
2042 return NULL;
2043 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002046}
2047
2048static void
2049kqueue_queue_dealloc(kqueue_queue_Object *self)
2050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 kqueue_queue_internal_close(self);
2052 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002053}
2054
2055static PyObject*
2056kqueue_queue_close(kqueue_queue_Object *self)
2057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 errno = kqueue_queue_internal_close(self);
2059 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002060 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 return NULL;
2062 }
2063 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002064}
2065
2066PyDoc_STRVAR(kqueue_queue_close_doc,
2067"close() -> None\n\
2068\n\
2069Close the kqueue control file descriptor. Further operations on the kqueue\n\
2070object will raise an exception.");
2071
2072static PyObject*
2073kqueue_queue_get_closed(kqueue_queue_Object *self)
2074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 if (self->kqfd < 0)
2076 Py_RETURN_TRUE;
2077 else
2078 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002079}
2080
2081static PyObject*
2082kqueue_queue_fileno(kqueue_queue_Object *self)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 if (self->kqfd < 0)
2085 return kqueue_queue_err_closed();
2086 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002087}
2088
2089PyDoc_STRVAR(kqueue_queue_fileno_doc,
2090"fileno() -> int\n\
2091\n\
2092Return the kqueue control file descriptor.");
2093
2094static PyObject*
2095kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2100 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002103}
2104
2105PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2106"fromfd(fd) -> kqueue\n\
2107\n\
2108Create a kqueue object from a given control fd.");
2109
2110static PyObject *
2111kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 int nevents = 0;
2114 int gotevents = 0;
2115 int nchanges = 0;
2116 int i = 0;
2117 PyObject *otimeout = NULL;
2118 PyObject *ch = NULL;
Serhiy Storchakade072102017-10-12 22:17:46 +03002119 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 PyObject *result = NULL;
2121 struct kevent *evl = NULL;
2122 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002123 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002125 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (self->kqfd < 0)
2128 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2131 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (nevents < 0) {
2134 PyErr_Format(PyExc_ValueError,
2135 "Length of eventlist must be 0 or positive, got %d",
2136 nevents);
2137 return NULL;
2138 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 if (otimeout == Py_None || otimeout == NULL) {
2141 ptimeoutspec = NULL;
2142 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002143 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002144 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002145 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002146 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002147 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002148 "or None, got %.200s",
2149 Py_TYPE(otimeout)->tp_name);
2150 return NULL;
2151 }
2152
Victor Stinner4448c082015-03-31 11:48:34 +02002153 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002154 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002155
Victor Stinner4448c082015-03-31 11:48:34 +02002156 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 PyErr_SetString(PyExc_ValueError,
2158 "timeout must be positive or None");
2159 return NULL;
2160 }
Victor Stinner4448c082015-03-31 11:48:34 +02002161 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 if (ch != NULL && ch != Py_None) {
Serhiy Storchakade072102017-10-12 22:17:46 +03002165 seq = PySequence_Fast(ch, "changelist is not iterable");
2166 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 return NULL;
2168 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002169 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2170 PyErr_SetString(PyExc_OverflowError,
2171 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 goto error;
2173 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002174 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 chl = PyMem_New(struct kevent, nchanges);
2177 if (chl == NULL) {
2178 PyErr_NoMemory();
2179 goto error;
2180 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002181 for (i = 0; i < nchanges; ++i) {
2182 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyErr_SetString(PyExc_TypeError,
2185 "changelist must be an iterable of "
2186 "select.kevent objects");
2187 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002189 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002191 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 /* event list */
2195 if (nevents) {
2196 evl = PyMem_New(struct kevent, nevents);
2197 if (evl == NULL) {
2198 PyErr_NoMemory();
2199 goto error;
2200 }
2201 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002202
Victor Stinner4448c082015-03-31 11:48:34 +02002203 if (ptimeoutspec)
2204 deadline = _PyTime_GetMonotonicClock() + timeout;
2205
2206 do {
2207 Py_BEGIN_ALLOW_THREADS
2208 errno = 0;
2209 gotevents = kevent(self->kqfd, chl, nchanges,
2210 evl, nevents, ptimeoutspec);
2211 Py_END_ALLOW_THREADS
2212
2213 if (errno != EINTR)
2214 break;
2215
2216 /* kevent() was interrupted by a signal */
2217 if (PyErr_CheckSignals())
2218 goto error;
2219
2220 if (ptimeoutspec) {
2221 timeout = deadline - _PyTime_GetMonotonicClock();
2222 if (timeout < 0) {
2223 gotevents = 0;
2224 break;
2225 }
2226 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2227 goto error;
2228 /* retry kevent() with the recomputed timeout */
2229 }
2230 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 if (gotevents == -1) {
2233 PyErr_SetFromErrno(PyExc_OSError);
2234 goto error;
2235 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 result = PyList_New(gotevents);
2238 if (result == NULL) {
2239 goto error;
2240 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 for (i = 0; i < gotevents; i++) {
2243 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2246 if (ch == NULL) {
2247 goto error;
2248 }
2249 ch->e = evl[i];
2250 PyList_SET_ITEM(result, i, (PyObject *)ch);
2251 }
2252 PyMem_Free(chl);
2253 PyMem_Free(evl);
2254 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255
2256 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 PyMem_Free(chl);
2258 PyMem_Free(evl);
2259 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002260 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262}
2263
2264PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002265"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002266\n\
2267Calls the kernel kevent function.\n\
Serhiy Storchakade072102017-10-12 22:17:46 +03002268- changelist must be an iterable of kevent objects describing the changes\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002269 to be made to the kernel's watch list or None.\n\
2270- max_events lets you specify the maximum number of events that the\n\
2271 kernel will return.\n\
2272- timeout is the maximum time to wait in seconds, or else None,\n\
2273 to wait forever. timeout accepts floats for smaller timeouts, too.");
2274
2275
2276static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2278 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2279 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2280 kqueue_queue_close_doc},
2281 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2282 kqueue_queue_fileno_doc},
2283 {"control", (PyCFunction)kqueue_queue_control,
2284 METH_VARARGS , kqueue_queue_control_doc},
2285 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002286};
2287
2288static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 {"closed", (getter)kqueue_queue_get_closed, NULL,
2290 "True if the kqueue handler is closed"},
2291 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002292};
2293
2294PyDoc_STRVAR(kqueue_queue_doc,
2295"Kqueue syscall wrapper.\n\
2296\n\
2297For example, to start watching a socket for input:\n\
2298>>> kq = kqueue()\n\
2299>>> sock = socket()\n\
2300>>> sock.connect((host, port))\n\
2301>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2302\n\
2303To wait one second for it to become writeable:\n\
2304>>> kq.control(None, 1, 1000)\n\
2305\n\
2306To stop listening:\n\
2307>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2308
2309static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 PyVarObject_HEAD_INIT(NULL, 0)
2311 "select.kqueue", /* tp_name */
2312 sizeof(kqueue_queue_Object), /* tp_basicsize */
2313 0, /* tp_itemsize */
2314 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2315 0, /* tp_print */
2316 0, /* tp_getattr */
2317 0, /* tp_setattr */
2318 0, /* tp_reserved */
2319 0, /* tp_repr */
2320 0, /* tp_as_number */
2321 0, /* tp_as_sequence */
2322 0, /* tp_as_mapping */
2323 0, /* tp_hash */
2324 0, /* tp_call */
2325 0, /* tp_str */
2326 0, /* tp_getattro */
2327 0, /* tp_setattro */
2328 0, /* tp_as_buffer */
2329 Py_TPFLAGS_DEFAULT, /* tp_flags */
2330 kqueue_queue_doc, /* tp_doc */
2331 0, /* tp_traverse */
2332 0, /* tp_clear */
2333 0, /* tp_richcompare */
2334 0, /* tp_weaklistoffset */
2335 0, /* tp_iter */
2336 0, /* tp_iternext */
2337 kqueue_queue_methods, /* tp_methods */
2338 0, /* tp_members */
2339 kqueue_queue_getsetlist, /* tp_getset */
2340 0, /* tp_base */
2341 0, /* tp_dict */
2342 0, /* tp_descr_get */
2343 0, /* tp_descr_set */
2344 0, /* tp_dictoffset */
2345 0, /* tp_init */
2346 0, /* tp_alloc */
2347 kqueue_queue_new, /* tp_new */
2348 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002349};
2350
2351#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002352
2353
2354
2355
2356
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002357/* ************************************************************************ */
2358
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002359PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002360"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2361\n\
2362Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002363The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002364rlist -- wait until ready for reading\n\
2365wlist -- wait until ready for writing\n\
2366xlist -- wait for an ``exceptional condition''\n\
2367If only one kind of condition is required, pass [] for the other lists.\n\
2368A file descriptor is either a socket or file object, or a small integer\n\
2369gotten from a fileno() method call on one of those.\n\
2370\n\
2371The optional 4th argument specifies a timeout in seconds; it may be\n\
2372a floating point number to specify fractions of seconds. If it is absent\n\
2373or None, the call will never time out.\n\
2374\n\
2375The return value is a tuple of three lists corresponding to the first three\n\
2376arguments; each contains the subset of the corresponding file descriptors\n\
2377that are ready.\n\
2378\n\
2379*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002380On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002381descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002382
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002383static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002385#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002387#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002388#ifdef HAVE_SYS_DEVPOLL_H
2389 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2390#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002392};
2393
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002394PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002395"This module supports asynchronous I/O on multiple file descriptors.\n\
2396\n\
2397*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002398On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002399
Martin v. Löwis1a214512008-06-11 05:26:20 +00002400
2401static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 PyModuleDef_HEAD_INIT,
2403 "select",
2404 module_doc,
2405 -1,
2406 select_methods,
2407 NULL,
2408 NULL,
2409 NULL,
2410 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002411};
2412
Jesus Cead8b9ae62011-11-14 19:07:41 +01002413
2414
2415
Mark Hammond62b1ab12002-07-23 06:31:15 +00002416PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002417PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 PyObject *m;
2420 m = PyModule_Create(&selectmodule);
2421 if (m == NULL)
2422 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002423
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002424 Py_INCREF(PyExc_OSError);
2425 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002426
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002427#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002428#ifdef HAVE_BROKEN_PIPE_BUF
2429#undef PIPE_BUF
2430#define PIPE_BUF 512
2431#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002432 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002433#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002434
Charles-François Natali986a56c2013-01-19 12:19:10 +01002435#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002436#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 if (select_have_broken_poll()) {
2438 if (PyObject_DelAttrString(m, "poll") == -1) {
2439 PyErr_Clear();
2440 }
2441 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002442#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002444#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 if (PyType_Ready(&poll_Type) < 0)
2446 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002447 PyModule_AddIntMacro(m, POLLIN);
2448 PyModule_AddIntMacro(m, POLLPRI);
2449 PyModule_AddIntMacro(m, POLLOUT);
2450 PyModule_AddIntMacro(m, POLLERR);
2451 PyModule_AddIntMacro(m, POLLHUP);
2452 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002453
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002454#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002455 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002456#endif
2457#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002458 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002459#endif
2460#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002461 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002462#endif
2463#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002464 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002465#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002466#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002467 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002468#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002469#ifdef POLLRDHUP
2470 /* Kernel 2.6.17+ */
2471 PyModule_AddIntMacro(m, POLLRDHUP);
2472#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002474#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002475
Jesus Cead8b9ae62011-11-14 19:07:41 +01002476#ifdef HAVE_SYS_DEVPOLL_H
2477 if (PyType_Ready(&devpoll_Type) < 0)
2478 return NULL;
2479#endif
2480
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002481#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2483 if (PyType_Ready(&pyEpoll_Type) < 0)
2484 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002486 Py_INCREF(&pyEpoll_Type);
2487 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002488
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002489 PyModule_AddIntMacro(m, EPOLLIN);
2490 PyModule_AddIntMacro(m, EPOLLOUT);
2491 PyModule_AddIntMacro(m, EPOLLPRI);
2492 PyModule_AddIntMacro(m, EPOLLERR);
2493 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002494#ifdef EPOLLRDHUP
2495 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002496 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002497#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002498 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002499#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002501 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002502#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002503#ifdef EPOLLEXCLUSIVE
2504 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2505#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002506
2507#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002508 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002509#endif
2510#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002511 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002512#endif
2513#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002514 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002515#endif
2516#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002517 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002518#endif
2519#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002520 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002521#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002522
Benjamin Peterson95c16622011-12-27 15:36:32 -06002523#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002524 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002525#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002526#endif /* HAVE_EPOLL */
2527
2528#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 kqueue_event_Type.tp_new = PyType_GenericNew;
2530 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2531 if(PyType_Ready(&kqueue_event_Type) < 0)
2532 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 Py_INCREF(&kqueue_event_Type);
2535 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002537 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2538 if(PyType_Ready(&kqueue_queue_Type) < 0)
2539 return NULL;
2540 Py_INCREF(&kqueue_queue_Type);
2541 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2542
2543 /* event filters */
2544 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2545 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002546#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002548#endif
2549#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002551#endif
2552#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002553 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002554#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002555#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002557#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002558#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002559 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002560#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 /* event flags */
2564 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2565 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2566 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2567 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2568 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2569 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002570
Berker Peksag7ec64562016-09-14 18:16:59 +03002571#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
2574#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2579 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002582#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002584#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2589 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2590 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2591 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2592 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2593 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2594 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002595#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2600 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2601 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2602 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2606 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2607 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002608#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609
2610 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002611#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2613 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002615#endif
2616
2617#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002619}