blob: 7f62ab111d1f3e3de2ab2e3b494f5960d66ffb94 [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
Tal Einat6dc57e22018-06-30 23:02:48 +030061/*[clinic input]
62module select
63class select.poll "pollObject *" "&poll_Type"
64class select.devpoll "devpollObject *" "&devpoll_Type"
65class select.epoll "pyEpoll_Object *" "&pyEpoll_Type"
66class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type"
67[clinic start generated code]*/
68/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/
69
70static int
71fildes_converter(PyObject *o, void *p)
72{
73 int fd;
74 int *pointer = (int *)p;
75 fd = PyObject_AsFileDescriptor(o);
76 if (fd == -1)
77 return 0;
78 *pointer = fd;
79 return 1;
80}
81
82/*[python input]
83class fildes_converter(CConverter):
84 type = 'int'
85 converter = 'fildes_converter'
86[python start generated code]*/
87/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/
88
Barry Warsawc1cb3601996-12-12 22:16:21 +000089/* list of Python objects and their file descriptor */
90typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 PyObject *obj; /* owned reference */
92 SOCKET fd;
93 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000094} pylist;
95
Barry Warsawc1cb3601996-12-12 22:16:21 +000096static void
Tim Peters4b046c22001-08-16 21:59:46 +000097reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000098{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020099 unsigned int i;
100 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200101 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 }
103 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104}
105
106
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000107/* returns -1 and sets the Python exception if an error occurred, otherwise
108 returns a number >= 0
109*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000110static int
Brett Cannon62dba4c2003-09-10 19:37:42 +0000111seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200114 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100115 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 PyObject* fast_seq = NULL;
117 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +0000118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
120 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Benjamin Petersone0edb8b2010-06-27 23:49:45 +0000122 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (!fast_seq)
124 return -1;
125
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100126 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 SOCKET v;
128
129 /* any intervening fileno() calls could decr this refcnt */
130 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200131 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 Py_INCREF(o);
134 v = PyObject_AsFileDescriptor( o );
135 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000136
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000137#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000139#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200140 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 PyErr_SetString(PyExc_ValueError,
142 "filedescriptor out of range in select()");
143 goto finally;
144 }
145 if (v > max)
146 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000147#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200151 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 PyErr_SetString(PyExc_ValueError,
153 "too many file descriptors in select()");
154 goto finally;
155 }
156 fd2obj[index].obj = o;
157 fd2obj[index].fd = v;
158 fd2obj[index].sentinel = 0;
159 fd2obj[++index].sentinel = -1;
160 }
161 Py_DECREF(fast_seq);
162 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000163
164 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 Py_XDECREF(o);
166 Py_DECREF(fast_seq);
167 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000168}
169
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000170/* returns NULL and sets the Python exception if an error occurred */
171static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000172set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 int i, j, count=0;
175 PyObject *list, *o;
176 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
179 if (FD_ISSET(fd2obj[j].fd, set))
180 count++;
181 }
182 list = PyList_New(count);
183 if (!list)
184 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 i = 0;
187 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
188 fd = fd2obj[j].fd;
189 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 o = fd2obj[j].obj;
191 fd2obj[j].obj = NULL;
192 /* transfer ownership */
193 if (PyList_SetItem(list, i, o) < 0)
194 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 i++;
197 }
198 }
199 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000200 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 Py_DECREF(list);
202 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000203}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000204
Barry Warsawb44740f2001-08-16 16:52:59 +0000205#undef SELECT_USES_HEAP
206#if FD_SETSIZE > 1024
207#define SELECT_USES_HEAP
208#endif /* FD_SETSIZE > 1024 */
209
Tal Einat6dc57e22018-06-30 23:02:48 +0300210/*[clinic input]
211select.select
212
213 rlist: object
214 wlist: object
215 xlist: object
216 timeout as timeout_obj: object = None
217 /
218
219Wait until one or more file descriptors are ready for some kind of I/O.
220
221The first three arguments are sequences of file descriptors to be waited for:
222rlist -- wait until ready for reading
223wlist -- wait until ready for writing
224xlist -- wait for an "exceptional condition"
225If only one kind of condition is required, pass [] for the other lists.
226
227A file descriptor is either a socket or file object, or a small integer
228gotten from a fileno() method call on one of those.
229
230The optional 4th argument specifies a timeout in seconds; it may be
231a floating point number to specify fractions of seconds. If it is absent
232or None, the call will never time out.
233
234The return value is a tuple of three lists corresponding to the first three
235arguments; each contains the subset of the corresponding file descriptors
236that are ready.
237
238*** IMPORTANT NOTICE ***
239On Windows, only sockets are supported; on Unix, all file
240descriptors can be used.
241[clinic start generated code]*/
242
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000243static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300244select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
245 PyObject *xlist, PyObject *timeout_obj)
246/*[clinic end generated code: output=2b3cfa824f7ae4cf input=177e72184352df25]*/
Guido van Rossumed233a51992-06-23 09:07:03 +0000247{
Barry Warsawb44740f2001-08-16 16:52:59 +0000248#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 /* XXX: All this should probably be implemented as follows:
252 * - find the highest descriptor we're interested in
253 * - add one
254 * - that's the size
255 * See: Stevens, APitUE, $12.5.1
256 */
257 pylist rfd2obj[FD_SETSIZE + 1];
258 pylist wfd2obj[FD_SETSIZE + 1];
259 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000260#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 PyObject *ret = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 int imax, omax, emax, max;
265 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200266 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000267
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200268 if (timeout_obj == Py_None)
269 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200271 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100272 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200273 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
274 PyErr_SetString(PyExc_TypeError,
275 "timeout must be a float or None");
276 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100277 return NULL;
278 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100279
Pablo Galindo2c15b292017-10-17 15:14:41 +0100280 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100281 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100282 if (tv.tv_sec < 0) {
283 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 return NULL;
285 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 tvp = &tv;
287 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000288
Barry Warsawb44740f2001-08-16 16:52:59 +0000289#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 /* Allocate memory for the lists */
291 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
292 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
293 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
294 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
295 if (rfd2obj) PyMem_DEL(rfd2obj);
296 if (wfd2obj) PyMem_DEL(wfd2obj);
297 if (efd2obj) PyMem_DEL(efd2obj);
298 return PyErr_NoMemory();
299 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000300#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 /* Convert sequences to fd_sets, and get maximum fd number
303 * propagates the Python exception set in seq2set()
304 */
305 rfd2obj[0].sentinel = -1;
306 wfd2obj[0].sentinel = -1;
307 efd2obj[0].sentinel = -1;
Tal Einat6dc57e22018-06-30 23:02:48 +0300308 if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300310 if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300312 if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 max = imax;
316 if (omax > max) max = omax;
317 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000318
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200319 if (tvp)
320 deadline = _PyTime_GetMonotonicClock() + timeout;
321
322 do {
323 Py_BEGIN_ALLOW_THREADS
324 errno = 0;
325 n = select(max, &ifdset, &ofdset, &efdset, tvp);
326 Py_END_ALLOW_THREADS
327
328 if (errno != EINTR)
329 break;
330
331 /* select() was interrupted by a signal */
332 if (PyErr_CheckSignals())
333 goto finally;
334
335 if (tvp) {
336 timeout = deadline - _PyTime_GetMonotonicClock();
337 if (timeout < 0) {
Oran Avraham7f524152018-12-05 22:36:03 +0200338 /* bpo-35310: lists were unmodified -- clear them explicitly */
339 FD_ZERO(&ifdset);
340 FD_ZERO(&ofdset);
341 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200342 n = 0;
343 break;
344 }
345 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200346 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200347 }
348 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000349
Thomas Heller106f4c72002-09-24 16:51:00 +0000350#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200352 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000354#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200356 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000358#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 else {
360 /* any of these three calls can raise an exception. it's more
361 convenient to test for this after all three calls... but
362 is that acceptable?
363 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300364 rlist = set2list(&ifdset, rfd2obj);
365 wlist = set2list(&ofdset, wfd2obj);
366 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (PyErr_Occurred())
368 ret = NULL;
369 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300370 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000371
Tal Einat6dc57e22018-06-30 23:02:48 +0300372 Py_XDECREF(rlist);
373 Py_XDECREF(wlist);
374 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 }
376
Barry Warsawc1cb3601996-12-12 22:16:21 +0000377 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 reap_obj(rfd2obj);
379 reap_obj(wfd2obj);
380 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000381#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 PyMem_DEL(rfd2obj);
383 PyMem_DEL(wfd2obj);
384 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000385#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000387}
388
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000389#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000391 * poll() support
392 */
393
394typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 PyObject_HEAD
396 PyObject *dict;
397 int ufd_uptodate;
398 int ufd_len;
399 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300400 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401} pollObject;
402
Jeremy Hylton938ace62002-07-17 16:30:39 +0000403static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406 contained within a pollObject. Return 1 on success, 0 on an error.
407*/
408
409static int
410update_ufd_array(pollObject *self)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 Py_ssize_t i, pos;
413 PyObject *key, *value;
414 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000415
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200416 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
418 if (self->ufds == NULL) {
419 self->ufds = old_ufds;
420 PyErr_NoMemory();
421 return 0;
422 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 i = pos = 0;
425 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200426 assert(i < self->ufd_len);
427 /* Never overflow */
428 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200429 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 i++;
431 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200432 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 self->ufd_uptodate = 1;
434 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Tal Einat6dc57e22018-06-30 23:02:48 +0300437/*[clinic input]
438select.poll.register
439
440 fd: fildes
441 either an integer, or an object with a fileno() method returning an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300442 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300443 an optional bitmask describing the type of events to check for
444 /
445
446Register a file descriptor with the polling object.
447[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448
449static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300450select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300451/*[clinic end generated code: output=0dc7173c800a4a65 input=f18711d9bb021e25]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452{
Tal Einat6dc57e22018-06-30 23:02:48 +0300453 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 /* Add entry to the internal dictionary: the key is the
457 file descriptor, and the value is the event mask. */
458 key = PyLong_FromLong(fd);
459 if (key == NULL)
460 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300461 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 if (value == NULL) {
463 Py_DECREF(key);
464 return NULL;
465 }
466 err = PyDict_SetItem(self->dict, key, value);
467 Py_DECREF(key);
468 Py_DECREF(value);
469 if (err < 0)
470 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 self->ufd_uptodate = 0;
473
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200474 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475}
476
Tal Einat6dc57e22018-06-30 23:02:48 +0300477
478/*[clinic input]
479select.poll.modify
480
481 fd: fildes
482 either an integer, or an object with a fileno() method returning
483 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300484 eventmask: unsigned_short
Tal Einat6dc57e22018-06-30 23:02:48 +0300485 a bitmask describing the type of events to check for
486 /
487
488Modify an already registered file descriptor.
489[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000490
491static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300492select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300493/*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000494{
Tal Einat6dc57e22018-06-30 23:02:48 +0300495 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Modify registered fd */
499 key = PyLong_FromLong(fd);
500 if (key == NULL)
501 return NULL;
502 if (PyDict_GetItem(self->dict, key) == NULL) {
503 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200504 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200505 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 return NULL;
507 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300508 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (value == NULL) {
510 Py_DECREF(key);
511 return NULL;
512 }
513 err = PyDict_SetItem(self->dict, key, value);
514 Py_DECREF(key);
515 Py_DECREF(value);
516 if (err < 0)
517 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 self->ufd_uptodate = 0;
520
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200521 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000522}
523
524
Tal Einat6dc57e22018-06-30 23:02:48 +0300525/*[clinic input]
526select.poll.unregister
527
528 fd: fildes
529 /
530
531Remove a file descriptor being tracked by the polling object.
532[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533
534static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300535select_poll_unregister_impl(pollObject *self, int fd)
536/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 /* Check whether the fd is already in the array */
541 key = PyLong_FromLong(fd);
542 if (key == NULL)
543 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 if (PyDict_DelItem(self->dict, key) == -1) {
546 Py_DECREF(key);
547 /* This will simply raise the KeyError set by PyDict_DelItem
548 if the file descriptor isn't registered. */
549 return NULL;
550 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 Py_DECREF(key);
553 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000554
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200555 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556}
557
Tal Einat6dc57e22018-06-30 23:02:48 +0300558/*[clinic input]
559select.poll.poll
560
561 timeout as timeout_obj: object = None
562 /
563
564Polls the set of registered file descriptors.
565
566Returns a list containing any descriptors that have events or errors to
567report, as a list of (fd, event) 2-tuples.
568[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000569
570static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300571select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
572/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000573{
Tal Einat6dc57e22018-06-30 23:02:48 +0300574 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200575 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200577 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200578 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000579
Tal Einat6dc57e22018-06-30 23:02:48 +0300580 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200581 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100582 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
584 PyErr_SetString(PyExc_TypeError,
585 "timeout must be an integer or None");
586 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200588 }
589
Pablo Galindo2c15b292017-10-17 15:14:41 +0100590 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200591 if (ms < INT_MIN || ms > INT_MAX) {
592 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200594 }
595
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200596 if (timeout >= 0) {
597 deadline = _PyTime_GetMonotonicClock() + timeout;
598 }
599 }
600
601 /* On some OSes, typically BSD-based ones, the timeout parameter of the
602 poll() syscall, when negative, must be exactly INFTIM, where defined,
603 or -1. See issue 31334. */
604 if (ms < 0) {
605#ifdef INFTIM
606 ms = INFTIM;
607#else
608 ms = -1;
609#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000611
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300612 /* Avoid concurrent poll() invocation, issue 8865 */
613 if (self->poll_running) {
614 PyErr_SetString(PyExc_RuntimeError,
615 "concurrent poll() invocation");
616 return NULL;
617 }
618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 /* Ensure the ufd array is up to date */
620 if (!self->ufd_uptodate)
621 if (update_ufd_array(self) == 0)
622 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300624 self->poll_running = 1;
625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200627 async_err = 0;
628 do {
629 Py_BEGIN_ALLOW_THREADS
630 errno = 0;
631 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
632 Py_END_ALLOW_THREADS
633
634 if (errno != EINTR)
635 break;
636
637 /* poll() was interrupted by a signal */
638 if (PyErr_CheckSignals()) {
639 async_err = 1;
640 break;
641 }
642
643 if (timeout >= 0) {
644 timeout = deadline - _PyTime_GetMonotonicClock();
645 if (timeout < 0) {
646 poll_result = 0;
647 break;
648 }
649 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
650 /* retry poll() with the recomputed timeout */
651 }
652 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000653
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300654 self->poll_running = 0;
655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200657 if (!async_err)
658 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 return NULL;
660 }
661
662 /* build the result list */
663
664 result_list = PyList_New(poll_result);
665 if (!result_list)
666 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200668 for (i = 0, j = 0; j < poll_result; j++) {
669 /* skip to the next fired descriptor */
670 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 i++;
672 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200673 /* if we hit a NULL return, set value to NULL
674 and break out of loop; code at end will
675 clean up result_list */
676 value = PyTuple_New(2);
677 if (value == NULL)
678 goto error;
679 num = PyLong_FromLong(self->ufds[i].fd);
680 if (num == NULL) {
681 Py_DECREF(value);
682 goto error;
683 }
684 PyTuple_SET_ITEM(value, 0, num);
685
686 /* The &0xffff is a workaround for AIX. 'revents'
687 is a 16-bit short, and IBM assigned POLLNVAL
688 to be 0x8000, so the conversion to int results
689 in a negative number. See SF bug #923315. */
690 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
691 if (num == NULL) {
692 Py_DECREF(value);
693 goto error;
694 }
695 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700696 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200697 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 }
699 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000700
701 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 Py_DECREF(result_list);
703 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000704}
705
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000706static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000707newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000708{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 pollObject *self;
710 self = PyObject_New(pollObject, &poll_Type);
711 if (self == NULL)
712 return NULL;
713 /* ufd_uptodate is a Boolean, denoting whether the
714 array pointed to by ufds matches the contents of the dictionary. */
715 self->ufd_uptodate = 0;
716 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300717 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 self->dict = PyDict_New();
719 if (self->dict == NULL) {
720 Py_DECREF(self);
721 return NULL;
722 }
723 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000724}
725
726static void
727poll_dealloc(pollObject *self)
728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 if (self->ufds != NULL)
730 PyMem_DEL(self->ufds);
731 Py_XDECREF(self->dict);
732 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000733}
734
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000735
Jesus Cead8b9ae62011-11-14 19:07:41 +0100736#ifdef HAVE_SYS_DEVPOLL_H
737typedef struct {
738 PyObject_HEAD
739 int fd_devpoll;
740 int max_n_fds;
741 int n_fds;
742 struct pollfd *fds;
743} devpollObject;
744
745static PyTypeObject devpoll_Type;
746
Victor Stinner13423c32013-08-22 00:19:50 +0200747static PyObject *
748devpoll_err_closed(void)
749{
750 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
751 return NULL;
752}
753
Jesus Cead8b9ae62011-11-14 19:07:41 +0100754static int devpoll_flush(devpollObject *self)
755{
756 int size, n;
757
758 if (!self->n_fds) return 0;
759
760 size = sizeof(struct pollfd)*self->n_fds;
761 self->n_fds = 0;
762
Victor Stinner54799672015-03-19 23:33:09 +0100763 n = _Py_write(self->fd_devpoll, self->fds, size);
764 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100765 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100766
Jesus Cead8b9ae62011-11-14 19:07:41 +0100767 if (n < size) {
768 /*
769 ** Data writed to /dev/poll is a binary data structure. It is not
770 ** clear what to do if a partial write occurred. For now, raise
771 ** an exception and see if we actually found this problem in
772 ** the wild.
773 ** See http://bugs.python.org/issue6397.
774 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300775 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100776 "Please, report at http://bugs.python.org/. "
777 "Data to report: Size tried: %d, actual size written: %d.",
778 size, n);
779 return -1;
780 }
781 return 0;
782}
783
784static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300785internal_devpoll_register(devpollObject *self, int fd,
786 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100787{
Victor Stinner13423c32013-08-22 00:19:50 +0200788 if (self->fd_devpoll < 0)
789 return devpoll_err_closed();
790
Jesus Cead8b9ae62011-11-14 19:07:41 +0100791 if (remove) {
792 self->fds[self->n_fds].fd = fd;
793 self->fds[self->n_fds].events = POLLREMOVE;
794
795 if (++self->n_fds == self->max_n_fds) {
796 if (devpoll_flush(self))
797 return NULL;
798 }
799 }
800
801 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200802 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100803
804 if (++self->n_fds == self->max_n_fds) {
805 if (devpoll_flush(self))
806 return NULL;
807 }
808
809 Py_RETURN_NONE;
810}
811
Tal Einat6dc57e22018-06-30 23:02:48 +0300812/*[clinic input]
813select.devpoll.register
814
815 fd: fildes
816 either an integer, or an object with a fileno() method returning
817 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300818 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300819 an optional bitmask describing the type of events to check for
820 /
821
822Register a file descriptor with the polling object.
823[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100824
825static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300826select_devpoll_register_impl(devpollObject *self, int fd,
827 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300828/*[clinic end generated code: output=6e07fe8b74abba0c input=5bd7cacc47a8ee46]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100829{
Tal Einat6dc57e22018-06-30 23:02:48 +0300830 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100831}
832
Tal Einat6dc57e22018-06-30 23:02:48 +0300833/*[clinic input]
834select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100835
Tal Einat6dc57e22018-06-30 23:02:48 +0300836 fd: fildes
837 either an integer, or an object with a fileno() method returning
838 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300839 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300840 an optional bitmask describing the type of events to check for
841 /
842
843Modify a possible already registered file descriptor.
844[clinic start generated code]*/
845
846static PyObject *
847select_devpoll_modify_impl(devpollObject *self, int fd,
848 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300849/*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100850{
Tal Einat6dc57e22018-06-30 23:02:48 +0300851 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100852}
853
Tal Einat6dc57e22018-06-30 23:02:48 +0300854/*[clinic input]
855select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100856
Tal Einat6dc57e22018-06-30 23:02:48 +0300857 fd: fildes
858 /
859
860Remove a file descriptor being tracked by the polling object.
861[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100862
863static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300864select_devpoll_unregister_impl(devpollObject *self, int fd)
865/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100866{
Victor Stinner13423c32013-08-22 00:19:50 +0200867 if (self->fd_devpoll < 0)
868 return devpoll_err_closed();
869
Jesus Cead8b9ae62011-11-14 19:07:41 +0100870 self->fds[self->n_fds].fd = fd;
871 self->fds[self->n_fds].events = POLLREMOVE;
872
873 if (++self->n_fds == self->max_n_fds) {
874 if (devpoll_flush(self))
875 return NULL;
876 }
877
878 Py_RETURN_NONE;
879}
880
Tal Einat6dc57e22018-06-30 23:02:48 +0300881/*[clinic input]
882select.devpoll.poll
883 timeout as timeout_obj: object = None
884 /
885
886Polls the set of registered file descriptors.
887
888Returns a list containing any descriptors that have events or errors to
889report, as a list of (fd, event) 2-tuples.
890[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100891
892static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300893select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
894/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100895{
896 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200897 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100898 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100899 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200900 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100901
Victor Stinner13423c32013-08-22 00:19:50 +0200902 if (self->fd_devpoll < 0)
903 return devpoll_err_closed();
904
Jesus Cead8b9ae62011-11-14 19:07:41 +0100905 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300906 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100907 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200908 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909 }
910 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200911 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100912 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200913 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
914 PyErr_SetString(PyExc_TypeError,
915 "timeout must be an integer or None");
916 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100917 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200918 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919
Pablo Galindo2c15b292017-10-17 15:14:41 +0100920 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200921 if (ms < -1 || ms > INT_MAX) {
922 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
923 return NULL;
924 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100925 }
926
927 if (devpoll_flush(self))
928 return NULL;
929
930 dvp.dp_fds = self->fds;
931 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100933
Victor Stinner45ca48b2015-03-31 12:10:33 +0200934 if (timeout >= 0)
935 deadline = _PyTime_GetMonotonicClock() + timeout;
936
937 do {
938 /* call devpoll() */
939 Py_BEGIN_ALLOW_THREADS
940 errno = 0;
941 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
942 Py_END_ALLOW_THREADS
943
944 if (errno != EINTR)
945 break;
946
947 /* devpoll() was interrupted by a signal */
948 if (PyErr_CheckSignals())
949 return NULL;
950
951 if (timeout >= 0) {
952 timeout = deadline - _PyTime_GetMonotonicClock();
953 if (timeout < 0) {
954 poll_result = 0;
955 break;
956 }
957 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
958 dvp.dp_timeout = (int)ms;
959 /* retry devpoll() with the recomputed timeout */
960 }
961 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100962
963 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300964 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100965 return NULL;
966 }
967
968 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100969 result_list = PyList_New(poll_result);
970 if (!result_list)
971 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200972
973 for (i = 0; i < poll_result; i++) {
974 num1 = PyLong_FromLong(self->fds[i].fd);
975 num2 = PyLong_FromLong(self->fds[i].revents);
976 if ((num1 == NULL) || (num2 == NULL)) {
977 Py_XDECREF(num1);
978 Py_XDECREF(num2);
979 goto error;
980 }
981 value = PyTuple_Pack(2, num1, num2);
982 Py_DECREF(num1);
983 Py_DECREF(num2);
984 if (value == NULL)
985 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -0700986 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100987 }
988
989 return result_list;
990
991 error:
992 Py_DECREF(result_list);
993 return NULL;
994}
995
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100996static int
997devpoll_internal_close(devpollObject *self)
998{
999 int save_errno = 0;
1000 if (self->fd_devpoll >= 0) {
1001 int fd = self->fd_devpoll;
1002 self->fd_devpoll = -1;
1003 Py_BEGIN_ALLOW_THREADS
1004 if (close(fd) < 0)
1005 save_errno = errno;
1006 Py_END_ALLOW_THREADS
1007 }
1008 return save_errno;
1009}
1010
Tal Einat6dc57e22018-06-30 23:02:48 +03001011/*[clinic input]
1012select.devpoll.close
1013
1014Close the devpoll file descriptor.
1015
1016Further operations on the devpoll object will raise an exception.
1017[clinic start generated code]*/
1018
1019static PyObject *
1020select_devpoll_close_impl(devpollObject *self)
1021/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001022{
1023 errno = devpoll_internal_close(self);
1024 if (errno < 0) {
1025 PyErr_SetFromErrno(PyExc_OSError);
1026 return NULL;
1027 }
1028 Py_RETURN_NONE;
1029}
1030
Victor Stinner13423c32013-08-22 00:19:50 +02001031static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001032devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001033{
1034 if (self->fd_devpoll < 0)
1035 Py_RETURN_TRUE;
1036 else
1037 Py_RETURN_FALSE;
1038}
1039
Tal Einat6dc57e22018-06-30 23:02:48 +03001040/*[clinic input]
1041select.devpoll.fileno
1042
1043Return the file descriptor.
1044[clinic start generated code]*/
1045
1046static PyObject *
1047select_devpoll_fileno_impl(devpollObject *self)
1048/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001049{
1050 if (self->fd_devpoll < 0)
1051 return devpoll_err_closed();
1052 return PyLong_FromLong(self->fd_devpoll);
1053}
1054
Victor Stinner13423c32013-08-22 00:19:50 +02001055static PyGetSetDef devpoll_getsetlist[] = {
1056 {"closed", (getter)devpoll_get_closed, NULL,
1057 "True if the devpoll object is closed"},
1058 {0},
1059};
1060
Jesus Cead8b9ae62011-11-14 19:07:41 +01001061static devpollObject *
1062newDevPollObject(void)
1063{
1064 devpollObject *self;
1065 int fd_devpoll, limit_result;
1066 struct pollfd *fds;
1067 struct rlimit limit;
1068
Jesus Cead8b9ae62011-11-14 19:07:41 +01001069 /*
1070 ** If we try to process more that getrlimit()
1071 ** fds, the kernel will give an error, so
1072 ** we set the limit here. It is a dynamic
1073 ** value, because we can change rlimit() anytime.
1074 */
1075 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001076 if (limit_result == -1) {
1077 PyErr_SetFromErrno(PyExc_OSError);
1078 return NULL;
1079 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001080
1081 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1082 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001084
1085 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1086 if (fds == NULL) {
1087 close(fd_devpoll);
1088 PyErr_NoMemory();
1089 return NULL;
1090 }
1091
1092 self = PyObject_New(devpollObject, &devpoll_Type);
1093 if (self == NULL) {
1094 close(fd_devpoll);
1095 PyMem_DEL(fds);
1096 return NULL;
1097 }
1098 self->fd_devpoll = fd_devpoll;
1099 self->max_n_fds = limit.rlim_cur;
1100 self->n_fds = 0;
1101 self->fds = fds;
1102
1103 return self;
1104}
1105
1106static void
1107devpoll_dealloc(devpollObject *self)
1108{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001109 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001110 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001111 PyObject_Del(self);
1112}
1113
Jesus Cead8b9ae62011-11-14 19:07:41 +01001114#endif /* HAVE_SYS_DEVPOLL_H */
1115
1116
Tal Einat6dc57e22018-06-30 23:02:48 +03001117/*[clinic input]
1118select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001119
Tal Einat6dc57e22018-06-30 23:02:48 +03001120Returns a polling object.
1121
1122This object supports registering and unregistering file descriptors, and then
1123polling them for I/O events.
1124[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001125
1126static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001127select_poll_impl(PyObject *module)
1128/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001131}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001132
Jesus Cead8b9ae62011-11-14 19:07:41 +01001133#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001134
1135/*[clinic input]
1136select.devpoll
1137
1138Returns a polling object.
1139
1140This object supports registering and unregistering file descriptors, and then
1141polling them for I/O events.
1142[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001143
1144static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001145select_devpoll_impl(PyObject *module)
1146/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001147{
1148 return (PyObject *)newDevPollObject();
1149}
1150#endif
1151
1152
Thomas Wouters477c8d52006-05-27 19:21:47 +00001153#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001155 * On some systems poll() sets errno on invalid file descriptors. We test
1156 * for this at runtime because this bug may be fixed or introduced between
1157 * OS releases.
1158 */
1159static int select_have_broken_poll(void)
1160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 int poll_test;
1162 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 /* Create a file descriptor to make invalid */
1167 if (pipe(filedes) < 0) {
1168 return 1;
1169 }
1170 poll_struct.fd = filedes[0];
1171 close(filedes[0]);
1172 close(filedes[1]);
1173 poll_test = poll(&poll_struct, 1, 0);
1174 if (poll_test < 0) {
1175 return 1;
1176 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1177 return 1;
1178 }
1179 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001180}
1181#endif /* __APPLE__ */
1182
1183#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001184
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001185#ifdef HAVE_EPOLL
1186/* **************************************************************************
1187 * epoll interface for Linux 2.6
1188 *
1189 * Written by Christian Heimes
1190 * Inspired by Twisted's _epoll.pyx and select.poll()
1191 */
1192
1193#ifdef HAVE_SYS_EPOLL_H
1194#include <sys/epoll.h>
1195#endif
1196
1197typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001199 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001200} pyEpoll_Object;
1201
1202static PyTypeObject pyEpoll_Type;
1203#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1204
1205static PyObject *
1206pyepoll_err_closed(void)
1207{
Victor Stinner13423c32013-08-22 00:19:50 +02001208 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001210}
1211
1212static int
1213pyepoll_internal_close(pyEpoll_Object *self)
1214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 int save_errno = 0;
1216 if (self->epfd >= 0) {
1217 int epfd = self->epfd;
1218 self->epfd = -1;
1219 Py_BEGIN_ALLOW_THREADS
1220 if (close(epfd) < 0)
1221 save_errno = errno;
1222 Py_END_ALLOW_THREADS
1223 }
1224 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001225}
1226
1227static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001228newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 assert(type != NULL && type->tp_alloc != NULL);
1233 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1234 if (self == NULL)
1235 return NULL;
1236
1237 if (fd == -1) {
1238 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001239#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001240 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1241#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001242 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001243#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 Py_END_ALLOW_THREADS
1245 }
1246 else {
1247 self->epfd = fd;
1248 }
1249 if (self->epfd < 0) {
1250 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001251 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 return NULL;
1253 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001254
1255#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001256 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001257 Py_DECREF(self);
1258 return NULL;
1259 }
1260#endif
1261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001263}
1264
1265
Tal Einat6dc57e22018-06-30 23:02:48 +03001266/*[clinic input]
1267@classmethod
1268select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001269
Tal Einat6dc57e22018-06-30 23:02:48 +03001270 sizehint: int = -1
1271 The expected number of events to be registered. It must be positive,
1272 or -1 to use the default. It is only used on older systems where
1273 epoll_create1() is not available; otherwise it has no effect (though its
1274 value is still checked).
1275 flags: int = 0
1276 Deprecated and completely ignored. However, when supplied, its value
1277 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1278
1279Returns an epolling object.
1280[clinic start generated code]*/
1281
1282static PyObject *
1283select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1284/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1285{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001286 if (sizehint == -1) {
1287 sizehint = FD_SETSIZE - 1;
1288 }
1289 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001290 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001291 return NULL;
1292 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001293
1294#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001295 if (flags && flags != EPOLL_CLOEXEC) {
1296 PyErr_SetString(PyExc_OSError, "invalid flags");
1297 return NULL;
1298 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001299#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001300
Berker Peksage2197d12016-09-26 23:30:41 +03001301 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001302}
1303
1304
1305static void
1306pyepoll_dealloc(pyEpoll_Object *self)
1307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 (void)pyepoll_internal_close(self);
1309 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001310}
1311
Tal Einat6dc57e22018-06-30 23:02:48 +03001312/*[clinic input]
1313select.epoll.close
1314
1315Close the epoll control file descriptor.
1316
1317Further operations on the epoll object will raise an exception.
1318[clinic start generated code]*/
1319
1320static PyObject *
1321select_epoll_close_impl(pyEpoll_Object *self)
1322/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 errno = pyepoll_internal_close(self);
1325 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001326 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 return NULL;
1328 }
1329 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001330}
1331
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332
1333static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001334pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (self->epfd < 0)
1337 Py_RETURN_TRUE;
1338 else
1339 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001340}
1341
Tal Einat6dc57e22018-06-30 23:02:48 +03001342/*[clinic input]
1343select.epoll.fileno
1344
1345Return the epoll control file descriptor.
1346[clinic start generated code]*/
1347
1348static PyObject *
1349select_epoll_fileno_impl(pyEpoll_Object *self)
1350/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 if (self->epfd < 0)
1353 return pyepoll_err_closed();
1354 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001355}
1356
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357
Tal Einat6dc57e22018-06-30 23:02:48 +03001358/*[clinic input]
1359@classmethod
1360select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361
Tal Einat6dc57e22018-06-30 23:02:48 +03001362 fd: int
1363 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364
Tal Einat6dc57e22018-06-30 23:02:48 +03001365Create an epoll object from a given control fd.
1366[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001367
1368static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001369select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1370/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1371{
1372 SOCKET s_fd = (SOCKET)fd;
1373 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1374}
1375
1376
1377static PyObject *
1378pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 struct epoll_event ev;
1381 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 if (epfd < 0)
1384 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001385
Guido van Rossumee07b942013-12-06 17:46:22 -08001386 switch (op) {
1387 case EPOLL_CTL_ADD:
1388 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 ev.events = events;
1390 ev.data.fd = fd;
1391 Py_BEGIN_ALLOW_THREADS
1392 result = epoll_ctl(epfd, op, fd, &ev);
1393 Py_END_ALLOW_THREADS
1394 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001395 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1397 * operation required a non-NULL pointer in event, even
1398 * though this argument is ignored. */
1399 Py_BEGIN_ALLOW_THREADS
1400 result = epoll_ctl(epfd, op, fd, &ev);
1401 if (errno == EBADF) {
1402 /* fd already closed */
1403 result = 0;
1404 errno = 0;
1405 }
1406 Py_END_ALLOW_THREADS
1407 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001408 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 result = -1;
1410 errno = EINVAL;
1411 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001414 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 return NULL;
1416 }
1417 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418}
1419
Tal Einat6dc57e22018-06-30 23:02:48 +03001420/*[clinic input]
1421select.epoll.register
1422
1423 fd: fildes
1424 the target file descriptor of the operation
1425 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1426 a bit set composed of the various EPOLL constants
1427
1428Registers a new fd or raises an OSError if the fd is already registered.
1429
1430The epoll interface supports all file descriptors that support poll.
1431[clinic start generated code]*/
1432
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001433static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001434select_epoll_register_impl(pyEpoll_Object *self, int fd,
1435 unsigned int eventmask)
1436/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437{
Tal Einat6dc57e22018-06-30 23:02:48 +03001438 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439}
1440
Tal Einat6dc57e22018-06-30 23:02:48 +03001441/*[clinic input]
1442select.epoll.modify
1443
1444 fd: fildes
1445 the target file descriptor of the operation
1446 eventmask: unsigned_int(bitwise=True)
1447 a bit set composed of the various EPOLL constants
1448
1449Modify event mask for a registered file descriptor.
1450[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001451
1452static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001453select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1454 unsigned int eventmask)
1455/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001456{
Tal Einat6dc57e22018-06-30 23:02:48 +03001457 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001458}
1459
Tal Einat6dc57e22018-06-30 23:02:48 +03001460/*[clinic input]
1461select.epoll.unregister
1462
1463 fd: fildes
1464 the target file descriptor of the operation
1465
1466Remove a registered file descriptor from the epoll object.
1467[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001468
1469static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001470select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1471/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001472{
Tal Einat6dc57e22018-06-30 23:02:48 +03001473 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474}
1475
Tal Einat6dc57e22018-06-30 23:02:48 +03001476/*[clinic input]
1477select.epoll.poll
1478
1479 timeout as timeout_obj: object = None
1480 the maximum time to wait in seconds (as float);
1481 a timeout of None or -1 makes poll wait indefinitely
1482 maxevents: int = -1
1483 the maximum number of events returned; -1 means no limit
1484
1485Wait for events on the epoll file descriptor.
1486
1487Returns a list containing any descriptors that have events to report,
1488as a list of (fd, events) 2-tuples.
1489[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001490
1491static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001492select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1493 int maxevents)
1494/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 int nfds, i;
1497 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001498 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001499 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (self->epfd < 0)
1502 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001503
Berker Peksagb690b9b2018-09-11 20:29:48 +03001504 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001505 /* epoll_wait() has a resolution of 1 millisecond, round towards
1506 infinity to wait at least timeout seconds. */
1507 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001508 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001509 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1510 PyErr_SetString(PyExc_TypeError,
1511 "timeout must be an integer or None");
1512 }
1513 return NULL;
1514 }
1515
1516 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1517 if (ms < INT_MIN || ms > INT_MAX) {
1518 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1519 return NULL;
1520 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001521 /* epoll_wait(2) treats all arbitrary negative numbers the same
1522 for the timeout argument, but -1 is the documented way to block
1523 indefinitely in the epoll_wait(2) documentation, so we set ms
1524 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001525
Berker Peksagb690b9b2018-09-11 20:29:48 +03001526 Note that we didn't use INFTIM here since it's non-standard and
1527 isn't available under Linux. */
1528 if (ms < 0) {
1529 ms = -1;
1530 }
1531
1532 if (timeout >= 0) {
1533 deadline = _PyTime_GetMonotonicClock() + timeout;
1534 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001538 maxevents = FD_SETSIZE-1;
1539 }
1540 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 PyErr_Format(PyExc_ValueError,
1542 "maxevents must be greater than 0, got %d",
1543 maxevents);
1544 return NULL;
1545 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001546
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001547 evs = PyMem_New(struct epoll_event, maxevents);
1548 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001549 PyErr_NoMemory();
1550 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552
Victor Stinner41eba222015-03-30 21:59:21 +02001553 do {
1554 Py_BEGIN_ALLOW_THREADS
1555 errno = 0;
1556 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1557 Py_END_ALLOW_THREADS
1558
1559 if (errno != EINTR)
1560 break;
1561
1562 /* poll() was interrupted by a signal */
1563 if (PyErr_CheckSignals())
1564 goto error;
1565
1566 if (timeout >= 0) {
1567 timeout = deadline - _PyTime_GetMonotonicClock();
1568 if (timeout < 0) {
1569 nfds = 0;
1570 break;
1571 }
1572 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1573 /* retry epoll_wait() with the recomputed timeout */
1574 }
1575 } while(1);
1576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001578 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 goto error;
1580 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 elist = PyList_New(nfds);
1583 if (elist == NULL) {
1584 goto error;
1585 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001588 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 if (etuple == NULL) {
1590 Py_CLEAR(elist);
1591 goto error;
1592 }
1593 PyList_SET_ITEM(elist, i, etuple);
1594 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001595
Christian Heimesf6cd9672008-03-26 13:45:42 +00001596 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001597 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001599}
1600
Tal Einat6dc57e22018-06-30 23:02:48 +03001601
1602/*[clinic input]
1603select.epoll.__enter__
1604
1605[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001607static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001608select_epoll___enter___impl(pyEpoll_Object *self)
1609/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001610{
1611 if (self->epfd < 0)
1612 return pyepoll_err_closed();
1613
1614 Py_INCREF(self);
1615 return (PyObject *)self;
1616}
1617
Tal Einat6dc57e22018-06-30 23:02:48 +03001618/*[clinic input]
1619select.epoll.__exit__
1620
1621 exc_type: object = None
1622 exc_value: object = None
1623 exc_tb: object = None
1624 /
1625
1626[clinic start generated code]*/
1627
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001628static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001629select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1630 PyObject *exc_value, PyObject *exc_tb)
1631/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001632{
1633 _Py_IDENTIFIER(close);
1634
Tal Einat6dc57e22018-06-30 23:02:48 +03001635 return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001636}
1637
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001638static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 {"closed", (getter)pyepoll_get_closed, NULL,
1640 "True if the epoll handler is closed"},
1641 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001642};
1643
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001644#endif /* HAVE_EPOLL */
1645
1646#ifdef HAVE_KQUEUE
1647/* **************************************************************************
1648 * kqueue interface for BSD
1649 *
1650 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1651 * All rights reserved.
1652 *
1653 * Redistribution and use in source and binary forms, with or without
1654 * modification, are permitted provided that the following conditions
1655 * are met:
1656 * 1. Redistributions of source code must retain the above copyright
1657 * notice, this list of conditions and the following disclaimer.
1658 * 2. Redistributions in binary form must reproduce the above copyright
1659 * notice, this list of conditions and the following disclaimer in the
1660 * documentation and/or other materials provided with the distribution.
1661 *
1662 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1663 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1664 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1665 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1666 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1667 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1668 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1669 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1670 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1671 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1672 * SUCH DAMAGE.
1673 */
1674
1675#ifdef HAVE_SYS_EVENT_H
1676#include <sys/event.h>
1677#endif
1678
1679PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001680"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001681\n\
1682This object is the equivalent of the struct kevent for the C API.\n\
1683\n\
1684See the kqueue manpage for more detailed information about the meaning\n\
1685of the arguments.\n\
1686\n\
1687One minor note: while you might hope that udata could store a\n\
1688reference to a python object, it cannot, because it is impossible to\n\
1689keep a proper reference count of the object once it's passed into the\n\
1690kernel. Therefore, I have restricted it to only storing an integer. I\n\
1691recommend ignoring it and simply using the 'ident' field to key off\n\
1692of. You could also set up a dictionary on the python side to store a\n\
1693udata->object mapping.");
1694
1695typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 PyObject_HEAD
1697 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001698} kqueue_event_Object;
1699
1700static PyTypeObject kqueue_event_Type;
1701
1702#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1703
1704typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 PyObject_HEAD
1706 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001707} kqueue_queue_Object;
1708
1709static PyTypeObject kqueue_queue_Type;
1710
1711#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1712
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001713#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1714# error uintptr_t does not match void *!
1715#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1716# define T_UINTPTRT T_ULONGLONG
1717# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001718# define UINTPTRT_FMT_UNIT "K"
1719# define INTPTRT_FMT_UNIT "L"
1720#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1721# define T_UINTPTRT T_ULONG
1722# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001723# define UINTPTRT_FMT_UNIT "k"
1724# define INTPTRT_FMT_UNIT "l"
1725#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1726# define T_UINTPTRT T_UINT
1727# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001728# define UINTPTRT_FMT_UNIT "I"
1729# define INTPTRT_FMT_UNIT "i"
1730#else
1731# error uintptr_t does not match int, long, or long long!
1732#endif
1733
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001734#if SIZEOF_LONG_LONG == 8
1735# define T_INT64 T_LONGLONG
1736# define INT64_FMT_UNIT "L"
1737#elif SIZEOF_LONG == 8
1738# define T_INT64 T_LONG
1739# define INT64_FMT_UNIT "l"
1740#elif SIZEOF_INT == 8
1741# define T_INT64 T_INT
1742# define INT64_FMT_UNIT "i"
1743#else
1744# define INT64_FMT_UNIT "_"
1745#endif
1746
1747#if SIZEOF_LONG_LONG == 4
1748# define T_UINT32 T_ULONGLONG
1749# define UINT32_FMT_UNIT "K"
1750#elif SIZEOF_LONG == 4
1751# define T_UINT32 T_ULONG
1752# define UINT32_FMT_UNIT "k"
1753#elif SIZEOF_INT == 4
1754# define T_UINT32 T_UINT
1755# define UINT32_FMT_UNIT "I"
1756#else
1757# define UINT32_FMT_UNIT "_"
1758#endif
1759
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001760/*
1761 * kevent is not standard and its members vary across BSDs.
1762 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001763#ifdef __NetBSD__
1764# define FILTER_TYPE T_UINT32
1765# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1766# define FLAGS_TYPE T_UINT32
1767# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1768# define FFLAGS_TYPE T_UINT32
1769# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001770#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001771# define FILTER_TYPE T_SHORT
1772# define FILTER_FMT_UNIT "h"
1773# define FLAGS_TYPE T_USHORT
1774# define FLAGS_FMT_UNIT "H"
1775# define FFLAGS_TYPE T_UINT
1776# define FFLAGS_FMT_UNIT "I"
1777#endif
1778
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001779#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001780# define DATA_TYPE T_INT64
1781# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001782#else
1783# define DATA_TYPE T_INTPTRT
1784# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001785#endif
1786
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001787/* Unfortunately, we can't store python objects in udata, because
1788 * kevents in the kernel can be removed without warning, which would
1789 * forever lose the refcount on the object stored with it.
1790 */
1791
1792#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1793static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001794 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1795 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1796 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001798 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1800 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001801};
1802#undef KQ_OFF
1803
1804static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001805
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001806kqueue_event_repr(kqueue_event_Object *s)
1807{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 char buf[1024];
1809 PyOS_snprintf(
1810 buf, sizeof(buf),
1811 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001812 "data=0x%llx udata=%p>",
1813 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1814 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001816}
1817
1818static int
1819kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 PyObject *pfd;
1822 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1823 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001824 static const char fmt[] = "O|"
1825 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1826 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1831 &pfd, &(self->e.filter), &(self->e.flags),
1832 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1833 return -1;
1834 }
1835
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001836 if (PyLong_Check(pfd)) {
1837 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 }
1839 else {
1840 self->e.ident = PyObject_AsFileDescriptor(pfd);
1841 }
1842 if (PyErr_Occurred()) {
1843 return -1;
1844 }
1845 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001846}
1847
1848static PyObject *
1849kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001851{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001852 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001855 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001857
1858#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1859 result = CMP(s->e.ident, o->e.ident)
1860 : CMP(s->e.filter, o->e.filter)
1861 : CMP(s->e.flags, o->e.flags)
1862 : CMP(s->e.fflags, o->e.fflags)
1863 : CMP(s->e.data, o->e.data)
1864 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1865 : 0;
1866#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001867
stratakise8b19652017-11-02 11:32:54 +01001868 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001869}
1870
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001871static PyObject *
1872kqueue_queue_err_closed(void)
1873{
Victor Stinner13423c32013-08-22 00:19:50 +02001874 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876}
1877
1878static int
1879kqueue_queue_internal_close(kqueue_queue_Object *self)
1880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 int save_errno = 0;
1882 if (self->kqfd >= 0) {
1883 int kqfd = self->kqfd;
1884 self->kqfd = -1;
1885 Py_BEGIN_ALLOW_THREADS
1886 if (close(kqfd) < 0)
1887 save_errno = errno;
1888 Py_END_ALLOW_THREADS
1889 }
1890 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891}
1892
1893static PyObject *
1894newKqueue_Object(PyTypeObject *type, SOCKET fd)
1895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 kqueue_queue_Object *self;
1897 assert(type != NULL && type->tp_alloc != NULL);
1898 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1899 if (self == NULL) {
1900 return NULL;
1901 }
1902
1903 if (fd == -1) {
1904 Py_BEGIN_ALLOW_THREADS
1905 self->kqfd = kqueue();
1906 Py_END_ALLOW_THREADS
1907 }
1908 else {
1909 self->kqfd = fd;
1910 }
1911 if (self->kqfd < 0) {
1912 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001913 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 return NULL;
1915 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001916
1917 if (fd == -1) {
1918 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1919 Py_DECREF(self);
1920 return NULL;
1921 }
1922 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001924}
1925
Tal Einat6dc57e22018-06-30 23:02:48 +03001926/*[clinic input]
1927@classmethod
1928select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001929
Tal Einat6dc57e22018-06-30 23:02:48 +03001930Kqueue syscall wrapper.
1931
1932For example, to start watching a socket for input:
1933>>> kq = kqueue()
1934>>> sock = socket()
1935>>> sock.connect((host, port))
1936>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1937
1938To wait one second for it to become writeable:
1939>>> kq.control(None, 1, 1000)
1940
1941To stop listening:
1942>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1943[clinic start generated code]*/
1944
1945static PyObject *
1946select_kqueue_impl(PyTypeObject *type)
1947/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001950}
1951
1952static void
1953kqueue_queue_dealloc(kqueue_queue_Object *self)
1954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 kqueue_queue_internal_close(self);
1956 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001957}
1958
Tal Einat6dc57e22018-06-30 23:02:48 +03001959/*[clinic input]
1960select.kqueue.close
1961
1962Close the kqueue control file descriptor.
1963
1964Further operations on the kqueue object will raise an exception.
1965[clinic start generated code]*/
1966
1967static PyObject *
1968select_kqueue_close_impl(kqueue_queue_Object *self)
1969/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 errno = kqueue_queue_internal_close(self);
1972 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001973 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 return NULL;
1975 }
1976 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001977}
1978
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001979static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001980kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 if (self->kqfd < 0)
1983 Py_RETURN_TRUE;
1984 else
1985 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001986}
1987
Tal Einat6dc57e22018-06-30 23:02:48 +03001988/*[clinic input]
1989select.kqueue.fileno
1990
1991Return the kqueue control file descriptor.
1992[clinic start generated code]*/
1993
1994static PyObject *
1995select_kqueue_fileno_impl(kqueue_queue_Object *self)
1996/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 if (self->kqfd < 0)
1999 return kqueue_queue_err_closed();
2000 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002001}
2002
Tal Einat6dc57e22018-06-30 23:02:48 +03002003/*[clinic input]
2004@classmethod
2005select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002006
Tal Einat6dc57e22018-06-30 23:02:48 +03002007 fd: int
2008 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002009
Tal Einat6dc57e22018-06-30 23:02:48 +03002010Create a kqueue object from a given control fd.
2011[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002012
2013static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002014select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2015/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002016{
Tal Einat6dc57e22018-06-30 23:02:48 +03002017 SOCKET s_fd = (SOCKET)fd;
2018
2019 return newKqueue_Object(type, s_fd);
2020}
2021
2022/*[clinic input]
2023select.kqueue.control
2024
2025 changelist: object
2026 Must be an iterable of kevent objects describing the changes to be made
2027 to the kernel's watch list or None.
2028 maxevents: int
2029 The maximum number of events that the kernel will return.
2030 timeout as otimeout: object = None
2031 The maximum time to wait in seconds, or else None to wait forever.
2032 This accepts floats for smaller timeouts, too.
2033 /
2034
2035Calls the kernel kevent function.
2036[clinic start generated code]*/
2037
2038static PyObject *
2039select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2040 int maxevents, PyObject *otimeout)
2041/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2042{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 int gotevents = 0;
2044 int nchanges = 0;
2045 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002046 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 PyObject *result = NULL;
2048 struct kevent *evl = NULL;
2049 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002050 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002052 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 if (self->kqfd < 0)
2055 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002056
Tal Einat6dc57e22018-06-30 23:02:48 +03002057 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 PyErr_Format(PyExc_ValueError,
2059 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002060 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 return NULL;
2062 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002063
Tal Einat6dc57e22018-06-30 23:02:48 +03002064 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 ptimeoutspec = NULL;
2066 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002067 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002068 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002069 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002070 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002071 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002072 "or None, got %.200s",
2073 Py_TYPE(otimeout)->tp_name);
2074 return NULL;
2075 }
2076
Victor Stinner4448c082015-03-31 11:48:34 +02002077 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002078 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002079
Victor Stinner4448c082015-03-31 11:48:34 +02002080 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 PyErr_SetString(PyExc_ValueError,
2082 "timeout must be positive or None");
2083 return NULL;
2084 }
Victor Stinner4448c082015-03-31 11:48:34 +02002085 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002087
Tal Einat6dc57e22018-06-30 23:02:48 +03002088 if (changelist != Py_None) {
2089 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002090 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 return NULL;
2092 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002093 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2094 PyErr_SetString(PyExc_OverflowError,
2095 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 goto error;
2097 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002098 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 chl = PyMem_New(struct kevent, nchanges);
2101 if (chl == NULL) {
2102 PyErr_NoMemory();
2103 goto error;
2104 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002105 for (i = 0; i < nchanges; ++i) {
2106 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 PyErr_SetString(PyExc_TypeError,
2109 "changelist must be an iterable of "
2110 "select.kevent objects");
2111 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002113 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002115 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002119 if (maxevents) {
2120 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 if (evl == NULL) {
2122 PyErr_NoMemory();
2123 goto error;
2124 }
2125 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Victor Stinner4448c082015-03-31 11:48:34 +02002127 if (ptimeoutspec)
2128 deadline = _PyTime_GetMonotonicClock() + timeout;
2129
2130 do {
2131 Py_BEGIN_ALLOW_THREADS
2132 errno = 0;
2133 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002134 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002135 Py_END_ALLOW_THREADS
2136
2137 if (errno != EINTR)
2138 break;
2139
2140 /* kevent() was interrupted by a signal */
2141 if (PyErr_CheckSignals())
2142 goto error;
2143
2144 if (ptimeoutspec) {
2145 timeout = deadline - _PyTime_GetMonotonicClock();
2146 if (timeout < 0) {
2147 gotevents = 0;
2148 break;
2149 }
2150 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2151 goto error;
2152 /* retry kevent() with the recomputed timeout */
2153 }
2154 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 if (gotevents == -1) {
2157 PyErr_SetFromErrno(PyExc_OSError);
2158 goto error;
2159 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 result = PyList_New(gotevents);
2162 if (result == NULL) {
2163 goto error;
2164 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 for (i = 0; i < gotevents; i++) {
2167 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2170 if (ch == NULL) {
2171 goto error;
2172 }
2173 ch->e = evl[i];
2174 PyList_SET_ITEM(result, i, (PyObject *)ch);
2175 }
2176 PyMem_Free(chl);
2177 PyMem_Free(evl);
2178 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002179
2180 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyMem_Free(chl);
2182 PyMem_Free(evl);
2183 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002184 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002186}
2187
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002188static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 {"closed", (getter)kqueue_queue_get_closed, NULL,
2190 "True if the kqueue handler is closed"},
2191 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002192};
2193
Tal Einat6dc57e22018-06-30 23:02:48 +03002194#endif /* HAVE_KQUEUE */
2195
2196
2197/* ************************************************************************ */
2198
2199#include "clinic/selectmodule.c.h"
2200
2201#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2202
2203static PyMethodDef poll_methods[] = {
2204 SELECT_POLL_REGISTER_METHODDEF
2205 SELECT_POLL_MODIFY_METHODDEF
2206 SELECT_POLL_UNREGISTER_METHODDEF
2207 SELECT_POLL_POLL_METHODDEF
2208 {NULL, NULL} /* sentinel */
2209};
2210
2211static PyTypeObject poll_Type = {
2212 /* The ob_type field must be initialized in the module init function
2213 * to be portable to Windows without using C++. */
2214 PyVarObject_HEAD_INIT(NULL, 0)
2215 "select.poll", /*tp_name*/
2216 sizeof(pollObject), /*tp_basicsize*/
2217 0, /*tp_itemsize*/
2218 /* methods */
2219 (destructor)poll_dealloc, /*tp_dealloc*/
2220 0, /*tp_print*/
2221 0, /*tp_getattr*/
2222 0, /*tp_setattr*/
2223 0, /*tp_reserved*/
2224 0, /*tp_repr*/
2225 0, /*tp_as_number*/
2226 0, /*tp_as_sequence*/
2227 0, /*tp_as_mapping*/
2228 0, /*tp_hash*/
2229 0, /*tp_call*/
2230 0, /*tp_str*/
2231 0, /*tp_getattro*/
2232 0, /*tp_setattro*/
2233 0, /*tp_as_buffer*/
2234 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2235 0, /*tp_doc*/
2236 0, /*tp_traverse*/
2237 0, /*tp_clear*/
2238 0, /*tp_richcompare*/
2239 0, /*tp_weaklistoffset*/
2240 0, /*tp_iter*/
2241 0, /*tp_iternext*/
2242 poll_methods, /*tp_methods*/
2243};
2244
2245#ifdef HAVE_SYS_DEVPOLL_H
2246
2247static PyMethodDef devpoll_methods[] = {
2248 SELECT_DEVPOLL_REGISTER_METHODDEF
2249 SELECT_DEVPOLL_MODIFY_METHODDEF
2250 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2251 SELECT_DEVPOLL_POLL_METHODDEF
2252 SELECT_DEVPOLL_CLOSE_METHODDEF
2253 SELECT_DEVPOLL_FILENO_METHODDEF
2254 {NULL, NULL} /* sentinel */
2255};
2256
2257static PyTypeObject devpoll_Type = {
2258 /* The ob_type field must be initialized in the module init function
2259 * to be portable to Windows without using C++. */
2260 PyVarObject_HEAD_INIT(NULL, 0)
2261 "select.devpoll", /*tp_name*/
2262 sizeof(devpollObject), /*tp_basicsize*/
2263 0, /*tp_itemsize*/
2264 /* methods */
2265 (destructor)devpoll_dealloc, /*tp_dealloc*/
2266 0, /*tp_print*/
2267 0, /*tp_getattr*/
2268 0, /*tp_setattr*/
2269 0, /*tp_reserved*/
2270 0, /*tp_repr*/
2271 0, /*tp_as_number*/
2272 0, /*tp_as_sequence*/
2273 0, /*tp_as_mapping*/
2274 0, /*tp_hash*/
2275 0, /*tp_call*/
2276 0, /*tp_str*/
2277 0, /*tp_getattro*/
2278 0, /*tp_setattro*/
2279 0, /*tp_as_buffer*/
2280 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2281 0, /*tp_doc*/
2282 0, /*tp_traverse*/
2283 0, /*tp_clear*/
2284 0, /*tp_richcompare*/
2285 0, /*tp_weaklistoffset*/
2286 0, /*tp_iter*/
2287 0, /*tp_iternext*/
2288 devpoll_methods, /*tp_methods*/
2289 0, /* tp_members */
2290 devpoll_getsetlist, /* tp_getset */
2291};
2292
2293#endif /* HAVE_SYS_DEVPOLL_H */
2294
2295#endif /* HAVE_POLL */
2296
2297#ifdef HAVE_EPOLL
2298
2299static PyMethodDef pyepoll_methods[] = {
2300 SELECT_EPOLL_FROMFD_METHODDEF
2301 SELECT_EPOLL_CLOSE_METHODDEF
2302 SELECT_EPOLL_FILENO_METHODDEF
2303 SELECT_EPOLL_MODIFY_METHODDEF
2304 SELECT_EPOLL_REGISTER_METHODDEF
2305 SELECT_EPOLL_UNREGISTER_METHODDEF
2306 SELECT_EPOLL_POLL_METHODDEF
2307 SELECT_EPOLL___ENTER___METHODDEF
2308 SELECT_EPOLL___EXIT___METHODDEF
2309 {NULL, NULL},
2310};
2311
2312static PyTypeObject pyEpoll_Type = {
2313 PyVarObject_HEAD_INIT(NULL, 0)
2314 "select.epoll", /* tp_name */
2315 sizeof(pyEpoll_Object), /* tp_basicsize */
2316 0, /* tp_itemsize */
2317 (destructor)pyepoll_dealloc, /* tp_dealloc */
2318 0, /* tp_print */
2319 0, /* tp_getattr */
2320 0, /* tp_setattr */
2321 0, /* tp_reserved */
2322 0, /* tp_repr */
2323 0, /* tp_as_number */
2324 0, /* tp_as_sequence */
2325 0, /* tp_as_mapping */
2326 0, /* tp_hash */
2327 0, /* tp_call */
2328 0, /* tp_str */
2329 PyObject_GenericGetAttr, /* tp_getattro */
2330 0, /* tp_setattro */
2331 0, /* tp_as_buffer */
2332 Py_TPFLAGS_DEFAULT, /* tp_flags */
2333 select_epoll__doc__, /* tp_doc */
2334 0, /* tp_traverse */
2335 0, /* tp_clear */
2336 0, /* tp_richcompare */
2337 0, /* tp_weaklistoffset */
2338 0, /* tp_iter */
2339 0, /* tp_iternext */
2340 pyepoll_methods, /* tp_methods */
2341 0, /* tp_members */
2342 pyepoll_getsetlist, /* tp_getset */
2343 0, /* tp_base */
2344 0, /* tp_dict */
2345 0, /* tp_descr_get */
2346 0, /* tp_descr_set */
2347 0, /* tp_dictoffset */
2348 0, /* tp_init */
2349 0, /* tp_alloc */
2350 select_epoll, /* tp_new */
2351 0, /* tp_free */
2352};
2353
2354#endif /* HAVE_EPOLL */
2355
2356#ifdef HAVE_KQUEUE
2357
2358static PyTypeObject kqueue_event_Type = {
2359 PyVarObject_HEAD_INIT(NULL, 0)
2360 "select.kevent", /* tp_name */
2361 sizeof(kqueue_event_Object), /* tp_basicsize */
2362 0, /* tp_itemsize */
2363 0, /* tp_dealloc */
2364 0, /* tp_print */
2365 0, /* tp_getattr */
2366 0, /* tp_setattr */
2367 0, /* tp_reserved */
2368 (reprfunc)kqueue_event_repr, /* tp_repr */
2369 0, /* tp_as_number */
2370 0, /* tp_as_sequence */
2371 0, /* tp_as_mapping */
2372 0, /* tp_hash */
2373 0, /* tp_call */
2374 0, /* tp_str */
2375 0, /* tp_getattro */
2376 0, /* tp_setattro */
2377 0, /* tp_as_buffer */
2378 Py_TPFLAGS_DEFAULT, /* tp_flags */
2379 kqueue_event_doc, /* tp_doc */
2380 0, /* tp_traverse */
2381 0, /* tp_clear */
2382 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
2383 0, /* tp_weaklistoffset */
2384 0, /* tp_iter */
2385 0, /* tp_iternext */
2386 0, /* tp_methods */
2387 kqueue_event_members, /* tp_members */
2388 0, /* tp_getset */
2389 0, /* tp_base */
2390 0, /* tp_dict */
2391 0, /* tp_descr_get */
2392 0, /* tp_descr_set */
2393 0, /* tp_dictoffset */
2394 (initproc)kqueue_event_init, /* tp_init */
2395 0, /* tp_alloc */
2396 0, /* tp_new */
2397 0, /* tp_free */
2398};
2399
2400static PyMethodDef kqueue_queue_methods[] = {
2401 SELECT_KQUEUE_FROMFD_METHODDEF
2402 SELECT_KQUEUE_CLOSE_METHODDEF
2403 SELECT_KQUEUE_FILENO_METHODDEF
2404 SELECT_KQUEUE_CONTROL_METHODDEF
2405 {NULL, NULL},
2406};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002407
2408static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 PyVarObject_HEAD_INIT(NULL, 0)
2410 "select.kqueue", /* tp_name */
2411 sizeof(kqueue_queue_Object), /* tp_basicsize */
2412 0, /* tp_itemsize */
2413 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2414 0, /* tp_print */
2415 0, /* tp_getattr */
2416 0, /* tp_setattr */
2417 0, /* tp_reserved */
2418 0, /* tp_repr */
2419 0, /* tp_as_number */
2420 0, /* tp_as_sequence */
2421 0, /* tp_as_mapping */
2422 0, /* tp_hash */
2423 0, /* tp_call */
2424 0, /* tp_str */
2425 0, /* tp_getattro */
2426 0, /* tp_setattro */
2427 0, /* tp_as_buffer */
2428 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tal Einat6dc57e22018-06-30 23:02:48 +03002429 select_kqueue__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 0, /* tp_traverse */
2431 0, /* tp_clear */
2432 0, /* tp_richcompare */
2433 0, /* tp_weaklistoffset */
2434 0, /* tp_iter */
2435 0, /* tp_iternext */
2436 kqueue_queue_methods, /* tp_methods */
2437 0, /* tp_members */
2438 kqueue_queue_getsetlist, /* tp_getset */
2439 0, /* tp_base */
2440 0, /* tp_dict */
2441 0, /* tp_descr_get */
2442 0, /* tp_descr_set */
2443 0, /* tp_dictoffset */
2444 0, /* tp_init */
2445 0, /* tp_alloc */
Tal Einat6dc57e22018-06-30 23:02:48 +03002446 select_kqueue, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002448};
2449
2450#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002451
2452
2453
2454
2455
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002456/* ************************************************************************ */
2457
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002458
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002459static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002460 SELECT_SELECT_METHODDEF
2461 SELECT_POLL_METHODDEF
2462 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002464};
2465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002466PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002467"This module supports asynchronous I/O on multiple file descriptors.\n\
2468\n\
2469*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002470On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002471
Martin v. Löwis1a214512008-06-11 05:26:20 +00002472
2473static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 PyModuleDef_HEAD_INIT,
2475 "select",
2476 module_doc,
2477 -1,
2478 select_methods,
2479 NULL,
2480 NULL,
2481 NULL,
2482 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002483};
2484
Jesus Cead8b9ae62011-11-14 19:07:41 +01002485
2486
2487
Mark Hammond62b1ab12002-07-23 06:31:15 +00002488PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002489PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 PyObject *m;
2492 m = PyModule_Create(&selectmodule);
2493 if (m == NULL)
2494 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002495
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002496 Py_INCREF(PyExc_OSError);
2497 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002498
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002499#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002500#ifdef HAVE_BROKEN_PIPE_BUF
2501#undef PIPE_BUF
2502#define PIPE_BUF 512
2503#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002504 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002505#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002506
Charles-François Natali986a56c2013-01-19 12:19:10 +01002507#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002508#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 if (select_have_broken_poll()) {
2510 if (PyObject_DelAttrString(m, "poll") == -1) {
2511 PyErr_Clear();
2512 }
2513 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002514#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002516#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 if (PyType_Ready(&poll_Type) < 0)
2518 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002519 PyModule_AddIntMacro(m, POLLIN);
2520 PyModule_AddIntMacro(m, POLLPRI);
2521 PyModule_AddIntMacro(m, POLLOUT);
2522 PyModule_AddIntMacro(m, POLLERR);
2523 PyModule_AddIntMacro(m, POLLHUP);
2524 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002525
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002526#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002527 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002528#endif
2529#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002530 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002531#endif
2532#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002533 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002534#endif
2535#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002536 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002537#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002538#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002539 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002540#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002541#ifdef POLLRDHUP
2542 /* Kernel 2.6.17+ */
2543 PyModule_AddIntMacro(m, POLLRDHUP);
2544#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002545 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002546#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002547
Jesus Cead8b9ae62011-11-14 19:07:41 +01002548#ifdef HAVE_SYS_DEVPOLL_H
2549 if (PyType_Ready(&devpoll_Type) < 0)
2550 return NULL;
2551#endif
2552
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002553#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002554 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2555 if (PyType_Ready(&pyEpoll_Type) < 0)
2556 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 Py_INCREF(&pyEpoll_Type);
2559 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002560
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002561 PyModule_AddIntMacro(m, EPOLLIN);
2562 PyModule_AddIntMacro(m, EPOLLOUT);
2563 PyModule_AddIntMacro(m, EPOLLPRI);
2564 PyModule_AddIntMacro(m, EPOLLERR);
2565 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002566#ifdef EPOLLRDHUP
2567 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002568 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002569#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002570 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002571#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002573 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002574#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002575#ifdef EPOLLEXCLUSIVE
2576 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2577#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002578
2579#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002580 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002581#endif
2582#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002583 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002584#endif
2585#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002586 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002587#endif
2588#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002589 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002590#endif
2591#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002592 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002593#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002594
Benjamin Peterson95c16622011-12-27 15:36:32 -06002595#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002596 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002597#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002598#endif /* HAVE_EPOLL */
2599
2600#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 kqueue_event_Type.tp_new = PyType_GenericNew;
2602 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2603 if(PyType_Ready(&kqueue_event_Type) < 0)
2604 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 Py_INCREF(&kqueue_event_Type);
2607 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2610 if(PyType_Ready(&kqueue_queue_Type) < 0)
2611 return NULL;
2612 Py_INCREF(&kqueue_queue_Type);
2613 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2614
2615 /* event filters */
2616 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2617 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002618#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#endif
2621#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002623#endif
2624#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002626#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002627#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002629#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002630#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002632#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 /* event flags */
2636 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2637 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2638 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2639 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2640 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2641 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002642
Berker Peksag7ec64562016-09-14 18:16:59 +03002643#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002645#endif
2646#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002648#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2651 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002654#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002656#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002659#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002660 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2661 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2662 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2663 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2664 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2665 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2666 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002667#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002670#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2672 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2673 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2674 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2675 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002677 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2678 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2679 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002680#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002681
2682 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002683#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2685 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2686 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002687#endif
2688
2689#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002690 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002691}