blob: ed71d8b0d59852d1eed5462f47fe078a47174f51 [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;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200502 if (PyDict_GetItemWithError(self->dict, key) == NULL) {
503 if (!PyErr_Occurred()) {
504 errno = ENOENT;
505 PyErr_SetFromErrno(PyExc_OSError);
506 }
Jesus Cea62a5c322012-07-19 21:31:26 +0200507 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 return NULL;
509 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300510 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (value == NULL) {
512 Py_DECREF(key);
513 return NULL;
514 }
515 err = PyDict_SetItem(self->dict, key, value);
516 Py_DECREF(key);
517 Py_DECREF(value);
518 if (err < 0)
519 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 self->ufd_uptodate = 0;
522
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200523 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000524}
525
526
Tal Einat6dc57e22018-06-30 23:02:48 +0300527/*[clinic input]
528select.poll.unregister
529
530 fd: fildes
531 /
532
533Remove a file descriptor being tracked by the polling object.
534[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000535
536static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300537select_poll_unregister_impl(pollObject *self, int fd)
538/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 /* Check whether the fd is already in the array */
543 key = PyLong_FromLong(fd);
544 if (key == NULL)
545 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 if (PyDict_DelItem(self->dict, key) == -1) {
548 Py_DECREF(key);
549 /* This will simply raise the KeyError set by PyDict_DelItem
550 if the file descriptor isn't registered. */
551 return NULL;
552 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 Py_DECREF(key);
555 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200557 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558}
559
Tal Einat6dc57e22018-06-30 23:02:48 +0300560/*[clinic input]
561select.poll.poll
562
563 timeout as timeout_obj: object = None
564 /
565
566Polls the set of registered file descriptors.
567
568Returns a list containing any descriptors that have events or errors to
569report, as a list of (fd, event) 2-tuples.
570[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000571
572static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300573select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
574/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000575{
Tal Einat6dc57e22018-06-30 23:02:48 +0300576 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200577 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200579 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200580 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000581
Tal Einat6dc57e22018-06-30 23:02:48 +0300582 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100584 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200585 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
586 PyErr_SetString(PyExc_TypeError,
587 "timeout must be an integer or None");
588 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200590 }
591
Pablo Galindo2c15b292017-10-17 15:14:41 +0100592 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200593 if (ms < INT_MIN || ms > INT_MAX) {
594 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200596 }
597
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200598 if (timeout >= 0) {
599 deadline = _PyTime_GetMonotonicClock() + timeout;
600 }
601 }
602
603 /* On some OSes, typically BSD-based ones, the timeout parameter of the
604 poll() syscall, when negative, must be exactly INFTIM, where defined,
605 or -1. See issue 31334. */
606 if (ms < 0) {
607#ifdef INFTIM
608 ms = INFTIM;
609#else
610 ms = -1;
611#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000613
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300614 /* Avoid concurrent poll() invocation, issue 8865 */
615 if (self->poll_running) {
616 PyErr_SetString(PyExc_RuntimeError,
617 "concurrent poll() invocation");
618 return NULL;
619 }
620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 /* Ensure the ufd array is up to date */
622 if (!self->ufd_uptodate)
623 if (update_ufd_array(self) == 0)
624 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000625
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300626 self->poll_running = 1;
627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200629 async_err = 0;
630 do {
631 Py_BEGIN_ALLOW_THREADS
632 errno = 0;
633 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
634 Py_END_ALLOW_THREADS
635
636 if (errno != EINTR)
637 break;
638
639 /* poll() was interrupted by a signal */
640 if (PyErr_CheckSignals()) {
641 async_err = 1;
642 break;
643 }
644
645 if (timeout >= 0) {
646 timeout = deadline - _PyTime_GetMonotonicClock();
647 if (timeout < 0) {
648 poll_result = 0;
649 break;
650 }
651 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
652 /* retry poll() with the recomputed timeout */
653 }
654 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300656 self->poll_running = 0;
657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200659 if (!async_err)
660 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 return NULL;
662 }
663
664 /* build the result list */
665
666 result_list = PyList_New(poll_result);
667 if (!result_list)
668 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200670 for (i = 0, j = 0; j < poll_result; j++) {
671 /* skip to the next fired descriptor */
672 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 i++;
674 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200675 /* if we hit a NULL return, set value to NULL
676 and break out of loop; code at end will
677 clean up result_list */
678 value = PyTuple_New(2);
679 if (value == NULL)
680 goto error;
681 num = PyLong_FromLong(self->ufds[i].fd);
682 if (num == NULL) {
683 Py_DECREF(value);
684 goto error;
685 }
686 PyTuple_SET_ITEM(value, 0, num);
687
688 /* The &0xffff is a workaround for AIX. 'revents'
689 is a 16-bit short, and IBM assigned POLLNVAL
690 to be 0x8000, so the conversion to int results
691 in a negative number. See SF bug #923315. */
692 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
693 if (num == NULL) {
694 Py_DECREF(value);
695 goto error;
696 }
697 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700698 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200699 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 }
701 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000702
703 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 Py_DECREF(result_list);
705 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000706}
707
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000708static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000709newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000710{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 pollObject *self;
712 self = PyObject_New(pollObject, &poll_Type);
713 if (self == NULL)
714 return NULL;
715 /* ufd_uptodate is a Boolean, denoting whether the
716 array pointed to by ufds matches the contents of the dictionary. */
717 self->ufd_uptodate = 0;
718 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300719 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 self->dict = PyDict_New();
721 if (self->dict == NULL) {
722 Py_DECREF(self);
723 return NULL;
724 }
725 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000726}
727
728static void
729poll_dealloc(pollObject *self)
730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 if (self->ufds != NULL)
732 PyMem_DEL(self->ufds);
733 Py_XDECREF(self->dict);
734 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000735}
736
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000737
Jesus Cead8b9ae62011-11-14 19:07:41 +0100738#ifdef HAVE_SYS_DEVPOLL_H
739typedef struct {
740 PyObject_HEAD
741 int fd_devpoll;
742 int max_n_fds;
743 int n_fds;
744 struct pollfd *fds;
745} devpollObject;
746
747static PyTypeObject devpoll_Type;
748
Victor Stinner13423c32013-08-22 00:19:50 +0200749static PyObject *
750devpoll_err_closed(void)
751{
752 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
753 return NULL;
754}
755
Jesus Cead8b9ae62011-11-14 19:07:41 +0100756static int devpoll_flush(devpollObject *self)
757{
758 int size, n;
759
760 if (!self->n_fds) return 0;
761
762 size = sizeof(struct pollfd)*self->n_fds;
763 self->n_fds = 0;
764
Victor Stinner54799672015-03-19 23:33:09 +0100765 n = _Py_write(self->fd_devpoll, self->fds, size);
766 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100767 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100768
Jesus Cead8b9ae62011-11-14 19:07:41 +0100769 if (n < size) {
770 /*
771 ** Data writed to /dev/poll is a binary data structure. It is not
772 ** clear what to do if a partial write occurred. For now, raise
773 ** an exception and see if we actually found this problem in
774 ** the wild.
775 ** See http://bugs.python.org/issue6397.
776 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300777 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100778 "Please, report at http://bugs.python.org/. "
779 "Data to report: Size tried: %d, actual size written: %d.",
780 size, n);
781 return -1;
782 }
783 return 0;
784}
785
786static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300787internal_devpoll_register(devpollObject *self, int fd,
788 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100789{
Victor Stinner13423c32013-08-22 00:19:50 +0200790 if (self->fd_devpoll < 0)
791 return devpoll_err_closed();
792
Jesus Cead8b9ae62011-11-14 19:07:41 +0100793 if (remove) {
794 self->fds[self->n_fds].fd = fd;
795 self->fds[self->n_fds].events = POLLREMOVE;
796
797 if (++self->n_fds == self->max_n_fds) {
798 if (devpoll_flush(self))
799 return NULL;
800 }
801 }
802
803 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200804 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100805
806 if (++self->n_fds == self->max_n_fds) {
807 if (devpoll_flush(self))
808 return NULL;
809 }
810
811 Py_RETURN_NONE;
812}
813
Tal Einat6dc57e22018-06-30 23:02:48 +0300814/*[clinic input]
815select.devpoll.register
816
817 fd: fildes
818 either an integer, or an object with a fileno() method returning
819 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300820 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300821 an optional bitmask describing the type of events to check for
822 /
823
824Register a file descriptor with the polling object.
825[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100826
827static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300828select_devpoll_register_impl(devpollObject *self, int fd,
829 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300830/*[clinic end generated code: output=6e07fe8b74abba0c input=5bd7cacc47a8ee46]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100831{
Tal Einat6dc57e22018-06-30 23:02:48 +0300832 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100833}
834
Tal Einat6dc57e22018-06-30 23:02:48 +0300835/*[clinic input]
836select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100837
Tal Einat6dc57e22018-06-30 23:02:48 +0300838 fd: fildes
839 either an integer, or an object with a fileno() method returning
840 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300841 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300842 an optional bitmask describing the type of events to check for
843 /
844
845Modify a possible already registered file descriptor.
846[clinic start generated code]*/
847
848static PyObject *
849select_devpoll_modify_impl(devpollObject *self, int fd,
850 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300851/*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100852{
Tal Einat6dc57e22018-06-30 23:02:48 +0300853 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100854}
855
Tal Einat6dc57e22018-06-30 23:02:48 +0300856/*[clinic input]
857select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100858
Tal Einat6dc57e22018-06-30 23:02:48 +0300859 fd: fildes
860 /
861
862Remove a file descriptor being tracked by the polling object.
863[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100864
865static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300866select_devpoll_unregister_impl(devpollObject *self, int fd)
867/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100868{
Victor Stinner13423c32013-08-22 00:19:50 +0200869 if (self->fd_devpoll < 0)
870 return devpoll_err_closed();
871
Jesus Cead8b9ae62011-11-14 19:07:41 +0100872 self->fds[self->n_fds].fd = fd;
873 self->fds[self->n_fds].events = POLLREMOVE;
874
875 if (++self->n_fds == self->max_n_fds) {
876 if (devpoll_flush(self))
877 return NULL;
878 }
879
880 Py_RETURN_NONE;
881}
882
Tal Einat6dc57e22018-06-30 23:02:48 +0300883/*[clinic input]
884select.devpoll.poll
885 timeout as timeout_obj: object = None
886 /
887
888Polls the set of registered file descriptors.
889
890Returns a list containing any descriptors that have events or errors to
891report, as a list of (fd, event) 2-tuples.
892[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100893
894static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300895select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
896/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100897{
898 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200899 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100900 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100901 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200902 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100903
Victor Stinner13423c32013-08-22 00:19:50 +0200904 if (self->fd_devpoll < 0)
905 return devpoll_err_closed();
906
Jesus Cead8b9ae62011-11-14 19:07:41 +0100907 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300908 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200910 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100911 }
912 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200913 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100914 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200915 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
916 PyErr_SetString(PyExc_TypeError,
917 "timeout must be an integer or None");
918 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200920 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100921
Pablo Galindo2c15b292017-10-17 15:14:41 +0100922 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200923 if (ms < -1 || ms > INT_MAX) {
924 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
925 return NULL;
926 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100927 }
928
929 if (devpoll_flush(self))
930 return NULL;
931
932 dvp.dp_fds = self->fds;
933 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200934 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100935
Victor Stinner45ca48b2015-03-31 12:10:33 +0200936 if (timeout >= 0)
937 deadline = _PyTime_GetMonotonicClock() + timeout;
938
939 do {
940 /* call devpoll() */
941 Py_BEGIN_ALLOW_THREADS
942 errno = 0;
943 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
944 Py_END_ALLOW_THREADS
945
946 if (errno != EINTR)
947 break;
948
949 /* devpoll() was interrupted by a signal */
950 if (PyErr_CheckSignals())
951 return NULL;
952
953 if (timeout >= 0) {
954 timeout = deadline - _PyTime_GetMonotonicClock();
955 if (timeout < 0) {
956 poll_result = 0;
957 break;
958 }
959 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
960 dvp.dp_timeout = (int)ms;
961 /* retry devpoll() with the recomputed timeout */
962 }
963 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100964
965 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300966 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100967 return NULL;
968 }
969
970 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100971 result_list = PyList_New(poll_result);
972 if (!result_list)
973 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200974
975 for (i = 0; i < poll_result; i++) {
976 num1 = PyLong_FromLong(self->fds[i].fd);
977 num2 = PyLong_FromLong(self->fds[i].revents);
978 if ((num1 == NULL) || (num2 == NULL)) {
979 Py_XDECREF(num1);
980 Py_XDECREF(num2);
981 goto error;
982 }
983 value = PyTuple_Pack(2, num1, num2);
984 Py_DECREF(num1);
985 Py_DECREF(num2);
986 if (value == NULL)
987 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -0700988 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100989 }
990
991 return result_list;
992
993 error:
994 Py_DECREF(result_list);
995 return NULL;
996}
997
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100998static int
999devpoll_internal_close(devpollObject *self)
1000{
1001 int save_errno = 0;
1002 if (self->fd_devpoll >= 0) {
1003 int fd = self->fd_devpoll;
1004 self->fd_devpoll = -1;
1005 Py_BEGIN_ALLOW_THREADS
1006 if (close(fd) < 0)
1007 save_errno = errno;
1008 Py_END_ALLOW_THREADS
1009 }
1010 return save_errno;
1011}
1012
Tal Einat6dc57e22018-06-30 23:02:48 +03001013/*[clinic input]
1014select.devpoll.close
1015
1016Close the devpoll file descriptor.
1017
1018Further operations on the devpoll object will raise an exception.
1019[clinic start generated code]*/
1020
1021static PyObject *
1022select_devpoll_close_impl(devpollObject *self)
1023/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001024{
1025 errno = devpoll_internal_close(self);
1026 if (errno < 0) {
1027 PyErr_SetFromErrno(PyExc_OSError);
1028 return NULL;
1029 }
1030 Py_RETURN_NONE;
1031}
1032
Victor Stinner13423c32013-08-22 00:19:50 +02001033static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001034devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001035{
1036 if (self->fd_devpoll < 0)
1037 Py_RETURN_TRUE;
1038 else
1039 Py_RETURN_FALSE;
1040}
1041
Tal Einat6dc57e22018-06-30 23:02:48 +03001042/*[clinic input]
1043select.devpoll.fileno
1044
1045Return the file descriptor.
1046[clinic start generated code]*/
1047
1048static PyObject *
1049select_devpoll_fileno_impl(devpollObject *self)
1050/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001051{
1052 if (self->fd_devpoll < 0)
1053 return devpoll_err_closed();
1054 return PyLong_FromLong(self->fd_devpoll);
1055}
1056
Victor Stinner13423c32013-08-22 00:19:50 +02001057static PyGetSetDef devpoll_getsetlist[] = {
1058 {"closed", (getter)devpoll_get_closed, NULL,
1059 "True if the devpoll object is closed"},
1060 {0},
1061};
1062
Jesus Cead8b9ae62011-11-14 19:07:41 +01001063static devpollObject *
1064newDevPollObject(void)
1065{
1066 devpollObject *self;
1067 int fd_devpoll, limit_result;
1068 struct pollfd *fds;
1069 struct rlimit limit;
1070
Jesus Cead8b9ae62011-11-14 19:07:41 +01001071 /*
1072 ** If we try to process more that getrlimit()
1073 ** fds, the kernel will give an error, so
1074 ** we set the limit here. It is a dynamic
1075 ** value, because we can change rlimit() anytime.
1076 */
1077 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001078 if (limit_result == -1) {
1079 PyErr_SetFromErrno(PyExc_OSError);
1080 return NULL;
1081 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001082
1083 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1084 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001085 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001086
1087 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1088 if (fds == NULL) {
1089 close(fd_devpoll);
1090 PyErr_NoMemory();
1091 return NULL;
1092 }
1093
1094 self = PyObject_New(devpollObject, &devpoll_Type);
1095 if (self == NULL) {
1096 close(fd_devpoll);
1097 PyMem_DEL(fds);
1098 return NULL;
1099 }
1100 self->fd_devpoll = fd_devpoll;
1101 self->max_n_fds = limit.rlim_cur;
1102 self->n_fds = 0;
1103 self->fds = fds;
1104
1105 return self;
1106}
1107
1108static void
1109devpoll_dealloc(devpollObject *self)
1110{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001111 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001112 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001113 PyObject_Del(self);
1114}
1115
Jesus Cead8b9ae62011-11-14 19:07:41 +01001116#endif /* HAVE_SYS_DEVPOLL_H */
1117
1118
Tal Einat6dc57e22018-06-30 23:02:48 +03001119/*[clinic input]
1120select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001121
Tal Einat6dc57e22018-06-30 23:02:48 +03001122Returns a polling object.
1123
1124This object supports registering and unregistering file descriptors, and then
1125polling them for I/O events.
1126[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001127
1128static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001129select_poll_impl(PyObject *module)
1130/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001133}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001134
Jesus Cead8b9ae62011-11-14 19:07:41 +01001135#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001136
1137/*[clinic input]
1138select.devpoll
1139
1140Returns a polling object.
1141
1142This object supports registering and unregistering file descriptors, and then
1143polling them for I/O events.
1144[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001145
1146static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001147select_devpoll_impl(PyObject *module)
1148/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001149{
1150 return (PyObject *)newDevPollObject();
1151}
1152#endif
1153
1154
Thomas Wouters477c8d52006-05-27 19:21:47 +00001155#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001157 * On some systems poll() sets errno on invalid file descriptors. We test
1158 * for this at runtime because this bug may be fixed or introduced between
1159 * OS releases.
1160 */
1161static int select_have_broken_poll(void)
1162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 int poll_test;
1164 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 /* Create a file descriptor to make invalid */
1169 if (pipe(filedes) < 0) {
1170 return 1;
1171 }
1172 poll_struct.fd = filedes[0];
1173 close(filedes[0]);
1174 close(filedes[1]);
1175 poll_test = poll(&poll_struct, 1, 0);
1176 if (poll_test < 0) {
1177 return 1;
1178 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1179 return 1;
1180 }
1181 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182}
1183#endif /* __APPLE__ */
1184
1185#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001186
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001187#ifdef HAVE_EPOLL
1188/* **************************************************************************
1189 * epoll interface for Linux 2.6
1190 *
1191 * Written by Christian Heimes
1192 * Inspired by Twisted's _epoll.pyx and select.poll()
1193 */
1194
1195#ifdef HAVE_SYS_EPOLL_H
1196#include <sys/epoll.h>
1197#endif
1198
1199typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001201 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001202} pyEpoll_Object;
1203
1204static PyTypeObject pyEpoll_Type;
1205#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1206
1207static PyObject *
1208pyepoll_err_closed(void)
1209{
Victor Stinner13423c32013-08-22 00:19:50 +02001210 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001212}
1213
1214static int
1215pyepoll_internal_close(pyEpoll_Object *self)
1216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 int save_errno = 0;
1218 if (self->epfd >= 0) {
1219 int epfd = self->epfd;
1220 self->epfd = -1;
1221 Py_BEGIN_ALLOW_THREADS
1222 if (close(epfd) < 0)
1223 save_errno = errno;
1224 Py_END_ALLOW_THREADS
1225 }
1226 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001227}
1228
1229static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001230newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 assert(type != NULL && type->tp_alloc != NULL);
1235 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1236 if (self == NULL)
1237 return NULL;
1238
1239 if (fd == -1) {
1240 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001241#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001242 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1243#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001244 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001245#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 Py_END_ALLOW_THREADS
1247 }
1248 else {
1249 self->epfd = fd;
1250 }
1251 if (self->epfd < 0) {
1252 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001253 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return NULL;
1255 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001256
1257#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001258 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001259 Py_DECREF(self);
1260 return NULL;
1261 }
1262#endif
1263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001265}
1266
1267
Tal Einat6dc57e22018-06-30 23:02:48 +03001268/*[clinic input]
1269@classmethod
1270select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001271
Tal Einat6dc57e22018-06-30 23:02:48 +03001272 sizehint: int = -1
1273 The expected number of events to be registered. It must be positive,
1274 or -1 to use the default. It is only used on older systems where
1275 epoll_create1() is not available; otherwise it has no effect (though its
1276 value is still checked).
1277 flags: int = 0
1278 Deprecated and completely ignored. However, when supplied, its value
1279 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1280
1281Returns an epolling object.
1282[clinic start generated code]*/
1283
1284static PyObject *
1285select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1286/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1287{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001288 if (sizehint == -1) {
1289 sizehint = FD_SETSIZE - 1;
1290 }
1291 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001292 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001293 return NULL;
1294 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001295
1296#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001297 if (flags && flags != EPOLL_CLOEXEC) {
1298 PyErr_SetString(PyExc_OSError, "invalid flags");
1299 return NULL;
1300 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001301#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001302
Berker Peksage2197d12016-09-26 23:30:41 +03001303 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001304}
1305
1306
1307static void
1308pyepoll_dealloc(pyEpoll_Object *self)
1309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 (void)pyepoll_internal_close(self);
1311 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001312}
1313
Tal Einat6dc57e22018-06-30 23:02:48 +03001314/*[clinic input]
1315select.epoll.close
1316
1317Close the epoll control file descriptor.
1318
1319Further operations on the epoll object will raise an exception.
1320[clinic start generated code]*/
1321
1322static PyObject *
1323select_epoll_close_impl(pyEpoll_Object *self)
1324/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 errno = pyepoll_internal_close(self);
1327 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001328 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 return NULL;
1330 }
1331 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332}
1333
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001334
1335static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001336pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 if (self->epfd < 0)
1339 Py_RETURN_TRUE;
1340 else
1341 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001342}
1343
Tal Einat6dc57e22018-06-30 23:02:48 +03001344/*[clinic input]
1345select.epoll.fileno
1346
1347Return the epoll control file descriptor.
1348[clinic start generated code]*/
1349
1350static PyObject *
1351select_epoll_fileno_impl(pyEpoll_Object *self)
1352/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 if (self->epfd < 0)
1355 return pyepoll_err_closed();
1356 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357}
1358
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359
Tal Einat6dc57e22018-06-30 23:02:48 +03001360/*[clinic input]
1361@classmethod
1362select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363
Tal Einat6dc57e22018-06-30 23:02:48 +03001364 fd: int
1365 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001366
Tal Einat6dc57e22018-06-30 23:02:48 +03001367Create an epoll object from a given control fd.
1368[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001369
1370static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001371select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1372/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1373{
1374 SOCKET s_fd = (SOCKET)fd;
1375 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1376}
1377
1378
1379static PyObject *
1380pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 struct epoll_event ev;
1383 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 if (epfd < 0)
1386 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001387
Guido van Rossumee07b942013-12-06 17:46:22 -08001388 switch (op) {
1389 case EPOLL_CTL_ADD:
1390 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 ev.events = events;
1392 ev.data.fd = fd;
1393 Py_BEGIN_ALLOW_THREADS
1394 result = epoll_ctl(epfd, op, fd, &ev);
1395 Py_END_ALLOW_THREADS
1396 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001397 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1399 * operation required a non-NULL pointer in event, even
1400 * though this argument is ignored. */
1401 Py_BEGIN_ALLOW_THREADS
1402 result = epoll_ctl(epfd, op, fd, &ev);
1403 if (errno == EBADF) {
1404 /* fd already closed */
1405 result = 0;
1406 errno = 0;
1407 }
1408 Py_END_ALLOW_THREADS
1409 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001410 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 result = -1;
1412 errno = EINVAL;
1413 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001416 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 return NULL;
1418 }
1419 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001420}
1421
Tal Einat6dc57e22018-06-30 23:02:48 +03001422/*[clinic input]
1423select.epoll.register
1424
1425 fd: fildes
1426 the target file descriptor of the operation
1427 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1428 a bit set composed of the various EPOLL constants
1429
1430Registers a new fd or raises an OSError if the fd is already registered.
1431
1432The epoll interface supports all file descriptors that support poll.
1433[clinic start generated code]*/
1434
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001435static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001436select_epoll_register_impl(pyEpoll_Object *self, int fd,
1437 unsigned int eventmask)
1438/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439{
Tal Einat6dc57e22018-06-30 23:02:48 +03001440 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441}
1442
Tal Einat6dc57e22018-06-30 23:02:48 +03001443/*[clinic input]
1444select.epoll.modify
1445
1446 fd: fildes
1447 the target file descriptor of the operation
1448 eventmask: unsigned_int(bitwise=True)
1449 a bit set composed of the various EPOLL constants
1450
1451Modify event mask for a registered file descriptor.
1452[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001453
1454static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001455select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1456 unsigned int eventmask)
1457/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001458{
Tal Einat6dc57e22018-06-30 23:02:48 +03001459 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001460}
1461
Tal Einat6dc57e22018-06-30 23:02:48 +03001462/*[clinic input]
1463select.epoll.unregister
1464
1465 fd: fildes
1466 the target file descriptor of the operation
1467
1468Remove a registered file descriptor from the epoll object.
1469[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001470
1471static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001472select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1473/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474{
Tal Einat6dc57e22018-06-30 23:02:48 +03001475 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476}
1477
Tal Einat6dc57e22018-06-30 23:02:48 +03001478/*[clinic input]
1479select.epoll.poll
1480
1481 timeout as timeout_obj: object = None
1482 the maximum time to wait in seconds (as float);
1483 a timeout of None or -1 makes poll wait indefinitely
1484 maxevents: int = -1
1485 the maximum number of events returned; -1 means no limit
1486
1487Wait for events on the epoll file descriptor.
1488
1489Returns a list containing any descriptors that have events to report,
1490as a list of (fd, events) 2-tuples.
1491[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001492
1493static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001494select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1495 int maxevents)
1496/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 int nfds, i;
1499 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001500 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001501 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 if (self->epfd < 0)
1504 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001505
Berker Peksagb690b9b2018-09-11 20:29:48 +03001506 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001507 /* epoll_wait() has a resolution of 1 millisecond, round towards
1508 infinity to wait at least timeout seconds. */
1509 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001510 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001511 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1512 PyErr_SetString(PyExc_TypeError,
1513 "timeout must be an integer or None");
1514 }
1515 return NULL;
1516 }
1517
1518 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1519 if (ms < INT_MIN || ms > INT_MAX) {
1520 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1521 return NULL;
1522 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001523 /* epoll_wait(2) treats all arbitrary negative numbers the same
1524 for the timeout argument, but -1 is the documented way to block
1525 indefinitely in the epoll_wait(2) documentation, so we set ms
1526 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001527
Berker Peksagb690b9b2018-09-11 20:29:48 +03001528 Note that we didn't use INFTIM here since it's non-standard and
1529 isn't available under Linux. */
1530 if (ms < 0) {
1531 ms = -1;
1532 }
1533
1534 if (timeout >= 0) {
1535 deadline = _PyTime_GetMonotonicClock() + timeout;
1536 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001540 maxevents = FD_SETSIZE-1;
1541 }
1542 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 PyErr_Format(PyExc_ValueError,
1544 "maxevents must be greater than 0, got %d",
1545 maxevents);
1546 return NULL;
1547 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001548
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001549 evs = PyMem_New(struct epoll_event, maxevents);
1550 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001551 PyErr_NoMemory();
1552 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001554
Victor Stinner41eba222015-03-30 21:59:21 +02001555 do {
1556 Py_BEGIN_ALLOW_THREADS
1557 errno = 0;
1558 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1559 Py_END_ALLOW_THREADS
1560
1561 if (errno != EINTR)
1562 break;
1563
1564 /* poll() was interrupted by a signal */
1565 if (PyErr_CheckSignals())
1566 goto error;
1567
1568 if (timeout >= 0) {
1569 timeout = deadline - _PyTime_GetMonotonicClock();
1570 if (timeout < 0) {
1571 nfds = 0;
1572 break;
1573 }
1574 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1575 /* retry epoll_wait() with the recomputed timeout */
1576 }
1577 } while(1);
1578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001580 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 goto error;
1582 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 elist = PyList_New(nfds);
1585 if (elist == NULL) {
1586 goto error;
1587 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001590 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 if (etuple == NULL) {
1592 Py_CLEAR(elist);
1593 goto error;
1594 }
1595 PyList_SET_ITEM(elist, i, etuple);
1596 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001597
Christian Heimesf6cd9672008-03-26 13:45:42 +00001598 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001599 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601}
1602
Tal Einat6dc57e22018-06-30 23:02:48 +03001603
1604/*[clinic input]
1605select.epoll.__enter__
1606
1607[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001608
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001609static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001610select_epoll___enter___impl(pyEpoll_Object *self)
1611/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001612{
1613 if (self->epfd < 0)
1614 return pyepoll_err_closed();
1615
1616 Py_INCREF(self);
1617 return (PyObject *)self;
1618}
1619
Tal Einat6dc57e22018-06-30 23:02:48 +03001620/*[clinic input]
1621select.epoll.__exit__
1622
1623 exc_type: object = None
1624 exc_value: object = None
1625 exc_tb: object = None
1626 /
1627
1628[clinic start generated code]*/
1629
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001630static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001631select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1632 PyObject *exc_value, PyObject *exc_tb)
1633/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001634{
1635 _Py_IDENTIFIER(close);
1636
Tal Einat6dc57e22018-06-30 23:02:48 +03001637 return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001638}
1639
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001640static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 {"closed", (getter)pyepoll_get_closed, NULL,
1642 "True if the epoll handler is closed"},
1643 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001644};
1645
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001646#endif /* HAVE_EPOLL */
1647
1648#ifdef HAVE_KQUEUE
1649/* **************************************************************************
1650 * kqueue interface for BSD
1651 *
1652 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1653 * All rights reserved.
1654 *
1655 * Redistribution and use in source and binary forms, with or without
1656 * modification, are permitted provided that the following conditions
1657 * are met:
1658 * 1. Redistributions of source code must retain the above copyright
1659 * notice, this list of conditions and the following disclaimer.
1660 * 2. Redistributions in binary form must reproduce the above copyright
1661 * notice, this list of conditions and the following disclaimer in the
1662 * documentation and/or other materials provided with the distribution.
1663 *
1664 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1665 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1666 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1667 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1668 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1669 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1670 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1671 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1672 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1673 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1674 * SUCH DAMAGE.
1675 */
1676
1677#ifdef HAVE_SYS_EVENT_H
1678#include <sys/event.h>
1679#endif
1680
1681PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001682"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001683\n\
1684This object is the equivalent of the struct kevent for the C API.\n\
1685\n\
1686See the kqueue manpage for more detailed information about the meaning\n\
1687of the arguments.\n\
1688\n\
1689One minor note: while you might hope that udata could store a\n\
1690reference to a python object, it cannot, because it is impossible to\n\
1691keep a proper reference count of the object once it's passed into the\n\
1692kernel. Therefore, I have restricted it to only storing an integer. I\n\
1693recommend ignoring it and simply using the 'ident' field to key off\n\
1694of. You could also set up a dictionary on the python side to store a\n\
1695udata->object mapping.");
1696
1697typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 PyObject_HEAD
1699 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001700} kqueue_event_Object;
1701
1702static PyTypeObject kqueue_event_Type;
1703
1704#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1705
1706typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 PyObject_HEAD
1708 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001709} kqueue_queue_Object;
1710
1711static PyTypeObject kqueue_queue_Type;
1712
1713#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1714
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001715#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1716# error uintptr_t does not match void *!
1717#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1718# define T_UINTPTRT T_ULONGLONG
1719# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001720# define UINTPTRT_FMT_UNIT "K"
1721# define INTPTRT_FMT_UNIT "L"
1722#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1723# define T_UINTPTRT T_ULONG
1724# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001725# define UINTPTRT_FMT_UNIT "k"
1726# define INTPTRT_FMT_UNIT "l"
1727#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1728# define T_UINTPTRT T_UINT
1729# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001730# define UINTPTRT_FMT_UNIT "I"
1731# define INTPTRT_FMT_UNIT "i"
1732#else
1733# error uintptr_t does not match int, long, or long long!
1734#endif
1735
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001736#if SIZEOF_LONG_LONG == 8
1737# define T_INT64 T_LONGLONG
1738# define INT64_FMT_UNIT "L"
1739#elif SIZEOF_LONG == 8
1740# define T_INT64 T_LONG
1741# define INT64_FMT_UNIT "l"
1742#elif SIZEOF_INT == 8
1743# define T_INT64 T_INT
1744# define INT64_FMT_UNIT "i"
1745#else
1746# define INT64_FMT_UNIT "_"
1747#endif
1748
1749#if SIZEOF_LONG_LONG == 4
1750# define T_UINT32 T_ULONGLONG
1751# define UINT32_FMT_UNIT "K"
1752#elif SIZEOF_LONG == 4
1753# define T_UINT32 T_ULONG
1754# define UINT32_FMT_UNIT "k"
1755#elif SIZEOF_INT == 4
1756# define T_UINT32 T_UINT
1757# define UINT32_FMT_UNIT "I"
1758#else
1759# define UINT32_FMT_UNIT "_"
1760#endif
1761
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001762/*
1763 * kevent is not standard and its members vary across BSDs.
1764 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001765#ifdef __NetBSD__
1766# define FILTER_TYPE T_UINT32
1767# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1768# define FLAGS_TYPE T_UINT32
1769# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1770# define FFLAGS_TYPE T_UINT32
1771# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001772#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001773# define FILTER_TYPE T_SHORT
1774# define FILTER_FMT_UNIT "h"
1775# define FLAGS_TYPE T_USHORT
1776# define FLAGS_FMT_UNIT "H"
1777# define FFLAGS_TYPE T_UINT
1778# define FFLAGS_FMT_UNIT "I"
1779#endif
1780
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001781#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001782# define DATA_TYPE T_INT64
1783# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001784#else
1785# define DATA_TYPE T_INTPTRT
1786# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001787#endif
1788
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001789/* Unfortunately, we can't store python objects in udata, because
1790 * kevents in the kernel can be removed without warning, which would
1791 * forever lose the refcount on the object stored with it.
1792 */
1793
1794#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1795static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001796 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1797 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1798 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001800 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1802 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001803};
1804#undef KQ_OFF
1805
1806static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001807
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001808kqueue_event_repr(kqueue_event_Object *s)
1809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 char buf[1024];
1811 PyOS_snprintf(
1812 buf, sizeof(buf),
1813 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001814 "data=0x%llx udata=%p>",
1815 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1816 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001818}
1819
1820static int
1821kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 PyObject *pfd;
1824 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1825 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001826 static const char fmt[] = "O|"
1827 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1828 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1833 &pfd, &(self->e.filter), &(self->e.flags),
1834 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1835 return -1;
1836 }
1837
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001838 if (PyLong_Check(pfd)) {
1839 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 }
1841 else {
1842 self->e.ident = PyObject_AsFileDescriptor(pfd);
1843 }
1844 if (PyErr_Occurred()) {
1845 return -1;
1846 }
1847 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001848}
1849
1850static PyObject *
1851kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001854 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001857 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001859
1860#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1861 result = CMP(s->e.ident, o->e.ident)
1862 : CMP(s->e.filter, o->e.filter)
1863 : CMP(s->e.flags, o->e.flags)
1864 : CMP(s->e.fflags, o->e.fflags)
1865 : CMP(s->e.data, o->e.data)
1866 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1867 : 0;
1868#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001869
stratakise8b19652017-11-02 11:32:54 +01001870 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001871}
1872
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873static PyObject *
1874kqueue_queue_err_closed(void)
1875{
Victor Stinner13423c32013-08-22 00:19:50 +02001876 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001878}
1879
1880static int
1881kqueue_queue_internal_close(kqueue_queue_Object *self)
1882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 int save_errno = 0;
1884 if (self->kqfd >= 0) {
1885 int kqfd = self->kqfd;
1886 self->kqfd = -1;
1887 Py_BEGIN_ALLOW_THREADS
1888 if (close(kqfd) < 0)
1889 save_errno = errno;
1890 Py_END_ALLOW_THREADS
1891 }
1892 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893}
1894
1895static PyObject *
1896newKqueue_Object(PyTypeObject *type, SOCKET fd)
1897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 kqueue_queue_Object *self;
1899 assert(type != NULL && type->tp_alloc != NULL);
1900 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1901 if (self == NULL) {
1902 return NULL;
1903 }
1904
1905 if (fd == -1) {
1906 Py_BEGIN_ALLOW_THREADS
1907 self->kqfd = kqueue();
1908 Py_END_ALLOW_THREADS
1909 }
1910 else {
1911 self->kqfd = fd;
1912 }
1913 if (self->kqfd < 0) {
1914 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001915 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 return NULL;
1917 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001918
1919 if (fd == -1) {
1920 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1921 Py_DECREF(self);
1922 return NULL;
1923 }
1924 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001926}
1927
Tal Einat6dc57e22018-06-30 23:02:48 +03001928/*[clinic input]
1929@classmethod
1930select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001931
Tal Einat6dc57e22018-06-30 23:02:48 +03001932Kqueue syscall wrapper.
1933
1934For example, to start watching a socket for input:
1935>>> kq = kqueue()
1936>>> sock = socket()
1937>>> sock.connect((host, port))
1938>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1939
1940To wait one second for it to become writeable:
1941>>> kq.control(None, 1, 1000)
1942
1943To stop listening:
1944>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1945[clinic start generated code]*/
1946
1947static PyObject *
1948select_kqueue_impl(PyTypeObject *type)
1949/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001952}
1953
1954static void
1955kqueue_queue_dealloc(kqueue_queue_Object *self)
1956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 kqueue_queue_internal_close(self);
1958 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001959}
1960
Tal Einat6dc57e22018-06-30 23:02:48 +03001961/*[clinic input]
1962select.kqueue.close
1963
1964Close the kqueue control file descriptor.
1965
1966Further operations on the kqueue object will raise an exception.
1967[clinic start generated code]*/
1968
1969static PyObject *
1970select_kqueue_close_impl(kqueue_queue_Object *self)
1971/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 errno = kqueue_queue_internal_close(self);
1974 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001975 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 return NULL;
1977 }
1978 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001979}
1980
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001981static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001982kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 if (self->kqfd < 0)
1985 Py_RETURN_TRUE;
1986 else
1987 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001988}
1989
Tal Einat6dc57e22018-06-30 23:02:48 +03001990/*[clinic input]
1991select.kqueue.fileno
1992
1993Return the kqueue control file descriptor.
1994[clinic start generated code]*/
1995
1996static PyObject *
1997select_kqueue_fileno_impl(kqueue_queue_Object *self)
1998/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 if (self->kqfd < 0)
2001 return kqueue_queue_err_closed();
2002 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003}
2004
Tal Einat6dc57e22018-06-30 23:02:48 +03002005/*[clinic input]
2006@classmethod
2007select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002008
Tal Einat6dc57e22018-06-30 23:02:48 +03002009 fd: int
2010 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002011
Tal Einat6dc57e22018-06-30 23:02:48 +03002012Create a kqueue object from a given control fd.
2013[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002014
2015static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002016select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2017/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002018{
Tal Einat6dc57e22018-06-30 23:02:48 +03002019 SOCKET s_fd = (SOCKET)fd;
2020
2021 return newKqueue_Object(type, s_fd);
2022}
2023
2024/*[clinic input]
2025select.kqueue.control
2026
2027 changelist: object
2028 Must be an iterable of kevent objects describing the changes to be made
2029 to the kernel's watch list or None.
2030 maxevents: int
2031 The maximum number of events that the kernel will return.
2032 timeout as otimeout: object = None
2033 The maximum time to wait in seconds, or else None to wait forever.
2034 This accepts floats for smaller timeouts, too.
2035 /
2036
2037Calls the kernel kevent function.
2038[clinic start generated code]*/
2039
2040static PyObject *
2041select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2042 int maxevents, PyObject *otimeout)
2043/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 int gotevents = 0;
2046 int nchanges = 0;
2047 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002048 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 PyObject *result = NULL;
2050 struct kevent *evl = NULL;
2051 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002052 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002054 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 if (self->kqfd < 0)
2057 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002058
Tal Einat6dc57e22018-06-30 23:02:48 +03002059 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 PyErr_Format(PyExc_ValueError,
2061 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002062 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 return NULL;
2064 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002065
Tal Einat6dc57e22018-06-30 23:02:48 +03002066 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 ptimeoutspec = NULL;
2068 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002069 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002070 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002071 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002072 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002073 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002074 "or None, got %.200s",
2075 Py_TYPE(otimeout)->tp_name);
2076 return NULL;
2077 }
2078
Victor Stinner4448c082015-03-31 11:48:34 +02002079 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002080 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002081
Victor Stinner4448c082015-03-31 11:48:34 +02002082 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 PyErr_SetString(PyExc_ValueError,
2084 "timeout must be positive or None");
2085 return NULL;
2086 }
Victor Stinner4448c082015-03-31 11:48:34 +02002087 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002089
Tal Einat6dc57e22018-06-30 23:02:48 +03002090 if (changelist != Py_None) {
2091 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002092 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 return NULL;
2094 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002095 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2096 PyErr_SetString(PyExc_OverflowError,
2097 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 goto error;
2099 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002100 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 chl = PyMem_New(struct kevent, nchanges);
2103 if (chl == NULL) {
2104 PyErr_NoMemory();
2105 goto error;
2106 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002107 for (i = 0; i < nchanges; ++i) {
2108 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 PyErr_SetString(PyExc_TypeError,
2111 "changelist must be an iterable of "
2112 "select.kevent objects");
2113 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002115 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002117 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002121 if (maxevents) {
2122 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 if (evl == NULL) {
2124 PyErr_NoMemory();
2125 goto error;
2126 }
2127 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002128
Victor Stinner4448c082015-03-31 11:48:34 +02002129 if (ptimeoutspec)
2130 deadline = _PyTime_GetMonotonicClock() + timeout;
2131
2132 do {
2133 Py_BEGIN_ALLOW_THREADS
2134 errno = 0;
2135 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002136 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002137 Py_END_ALLOW_THREADS
2138
2139 if (errno != EINTR)
2140 break;
2141
2142 /* kevent() was interrupted by a signal */
2143 if (PyErr_CheckSignals())
2144 goto error;
2145
2146 if (ptimeoutspec) {
2147 timeout = deadline - _PyTime_GetMonotonicClock();
2148 if (timeout < 0) {
2149 gotevents = 0;
2150 break;
2151 }
2152 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2153 goto error;
2154 /* retry kevent() with the recomputed timeout */
2155 }
2156 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 if (gotevents == -1) {
2159 PyErr_SetFromErrno(PyExc_OSError);
2160 goto error;
2161 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 result = PyList_New(gotevents);
2164 if (result == NULL) {
2165 goto error;
2166 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 for (i = 0; i < gotevents; i++) {
2169 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2172 if (ch == NULL) {
2173 goto error;
2174 }
2175 ch->e = evl[i];
2176 PyList_SET_ITEM(result, i, (PyObject *)ch);
2177 }
2178 PyMem_Free(chl);
2179 PyMem_Free(evl);
2180 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002181
2182 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 PyMem_Free(chl);
2184 PyMem_Free(evl);
2185 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002186 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002188}
2189
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002190static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 {"closed", (getter)kqueue_queue_get_closed, NULL,
2192 "True if the kqueue handler is closed"},
2193 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002194};
2195
Tal Einat6dc57e22018-06-30 23:02:48 +03002196#endif /* HAVE_KQUEUE */
2197
2198
2199/* ************************************************************************ */
2200
2201#include "clinic/selectmodule.c.h"
2202
2203#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2204
2205static PyMethodDef poll_methods[] = {
2206 SELECT_POLL_REGISTER_METHODDEF
2207 SELECT_POLL_MODIFY_METHODDEF
2208 SELECT_POLL_UNREGISTER_METHODDEF
2209 SELECT_POLL_POLL_METHODDEF
2210 {NULL, NULL} /* sentinel */
2211};
2212
2213static PyTypeObject poll_Type = {
2214 /* The ob_type field must be initialized in the module init function
2215 * to be portable to Windows without using C++. */
2216 PyVarObject_HEAD_INIT(NULL, 0)
2217 "select.poll", /*tp_name*/
2218 sizeof(pollObject), /*tp_basicsize*/
2219 0, /*tp_itemsize*/
2220 /* methods */
2221 (destructor)poll_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002222 0, /*tp_vectorcall_offset*/
Tal Einat6dc57e22018-06-30 23:02:48 +03002223 0, /*tp_getattr*/
2224 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002225 0, /*tp_as_async*/
Tal Einat6dc57e22018-06-30 23:02:48 +03002226 0, /*tp_repr*/
2227 0, /*tp_as_number*/
2228 0, /*tp_as_sequence*/
2229 0, /*tp_as_mapping*/
2230 0, /*tp_hash*/
2231 0, /*tp_call*/
2232 0, /*tp_str*/
2233 0, /*tp_getattro*/
2234 0, /*tp_setattro*/
2235 0, /*tp_as_buffer*/
2236 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2237 0, /*tp_doc*/
2238 0, /*tp_traverse*/
2239 0, /*tp_clear*/
2240 0, /*tp_richcompare*/
2241 0, /*tp_weaklistoffset*/
2242 0, /*tp_iter*/
2243 0, /*tp_iternext*/
2244 poll_methods, /*tp_methods*/
2245};
2246
2247#ifdef HAVE_SYS_DEVPOLL_H
2248
2249static PyMethodDef devpoll_methods[] = {
2250 SELECT_DEVPOLL_REGISTER_METHODDEF
2251 SELECT_DEVPOLL_MODIFY_METHODDEF
2252 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2253 SELECT_DEVPOLL_POLL_METHODDEF
2254 SELECT_DEVPOLL_CLOSE_METHODDEF
2255 SELECT_DEVPOLL_FILENO_METHODDEF
2256 {NULL, NULL} /* sentinel */
2257};
2258
2259static PyTypeObject devpoll_Type = {
2260 /* The ob_type field must be initialized in the module init function
2261 * to be portable to Windows without using C++. */
2262 PyVarObject_HEAD_INIT(NULL, 0)
2263 "select.devpoll", /*tp_name*/
2264 sizeof(devpollObject), /*tp_basicsize*/
2265 0, /*tp_itemsize*/
2266 /* methods */
2267 (destructor)devpoll_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002268 0, /*tp_vectorcall_offset*/
Tal Einat6dc57e22018-06-30 23:02:48 +03002269 0, /*tp_getattr*/
2270 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002271 0, /*tp_as_async*/
Tal Einat6dc57e22018-06-30 23:02:48 +03002272 0, /*tp_repr*/
2273 0, /*tp_as_number*/
2274 0, /*tp_as_sequence*/
2275 0, /*tp_as_mapping*/
2276 0, /*tp_hash*/
2277 0, /*tp_call*/
2278 0, /*tp_str*/
2279 0, /*tp_getattro*/
2280 0, /*tp_setattro*/
2281 0, /*tp_as_buffer*/
2282 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2283 0, /*tp_doc*/
2284 0, /*tp_traverse*/
2285 0, /*tp_clear*/
2286 0, /*tp_richcompare*/
2287 0, /*tp_weaklistoffset*/
2288 0, /*tp_iter*/
2289 0, /*tp_iternext*/
2290 devpoll_methods, /*tp_methods*/
2291 0, /* tp_members */
2292 devpoll_getsetlist, /* tp_getset */
2293};
2294
2295#endif /* HAVE_SYS_DEVPOLL_H */
2296
2297#endif /* HAVE_POLL */
2298
2299#ifdef HAVE_EPOLL
2300
2301static PyMethodDef pyepoll_methods[] = {
2302 SELECT_EPOLL_FROMFD_METHODDEF
2303 SELECT_EPOLL_CLOSE_METHODDEF
2304 SELECT_EPOLL_FILENO_METHODDEF
2305 SELECT_EPOLL_MODIFY_METHODDEF
2306 SELECT_EPOLL_REGISTER_METHODDEF
2307 SELECT_EPOLL_UNREGISTER_METHODDEF
2308 SELECT_EPOLL_POLL_METHODDEF
2309 SELECT_EPOLL___ENTER___METHODDEF
2310 SELECT_EPOLL___EXIT___METHODDEF
2311 {NULL, NULL},
2312};
2313
2314static PyTypeObject pyEpoll_Type = {
2315 PyVarObject_HEAD_INIT(NULL, 0)
2316 "select.epoll", /* tp_name */
2317 sizeof(pyEpoll_Object), /* tp_basicsize */
2318 0, /* tp_itemsize */
2319 (destructor)pyepoll_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002320 0, /* tp_vectorcall_offset */
Tal Einat6dc57e22018-06-30 23:02:48 +03002321 0, /* tp_getattr */
2322 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002323 0, /* tp_as_async */
Tal Einat6dc57e22018-06-30 23:02:48 +03002324 0, /* tp_repr */
2325 0, /* tp_as_number */
2326 0, /* tp_as_sequence */
2327 0, /* tp_as_mapping */
2328 0, /* tp_hash */
2329 0, /* tp_call */
2330 0, /* tp_str */
2331 PyObject_GenericGetAttr, /* tp_getattro */
2332 0, /* tp_setattro */
2333 0, /* tp_as_buffer */
2334 Py_TPFLAGS_DEFAULT, /* tp_flags */
2335 select_epoll__doc__, /* tp_doc */
2336 0, /* tp_traverse */
2337 0, /* tp_clear */
2338 0, /* tp_richcompare */
2339 0, /* tp_weaklistoffset */
2340 0, /* tp_iter */
2341 0, /* tp_iternext */
2342 pyepoll_methods, /* tp_methods */
2343 0, /* tp_members */
2344 pyepoll_getsetlist, /* tp_getset */
2345 0, /* tp_base */
2346 0, /* tp_dict */
2347 0, /* tp_descr_get */
2348 0, /* tp_descr_set */
2349 0, /* tp_dictoffset */
2350 0, /* tp_init */
2351 0, /* tp_alloc */
2352 select_epoll, /* tp_new */
2353 0, /* tp_free */
2354};
2355
2356#endif /* HAVE_EPOLL */
2357
2358#ifdef HAVE_KQUEUE
2359
2360static PyTypeObject kqueue_event_Type = {
2361 PyVarObject_HEAD_INIT(NULL, 0)
2362 "select.kevent", /* tp_name */
2363 sizeof(kqueue_event_Object), /* tp_basicsize */
2364 0, /* tp_itemsize */
2365 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002366 0, /* tp_vectorcall_offset */
Tal Einat6dc57e22018-06-30 23:02:48 +03002367 0, /* tp_getattr */
2368 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002369 0, /* tp_as_async */
Tal Einat6dc57e22018-06-30 23:02:48 +03002370 (reprfunc)kqueue_event_repr, /* tp_repr */
2371 0, /* tp_as_number */
2372 0, /* tp_as_sequence */
2373 0, /* tp_as_mapping */
2374 0, /* tp_hash */
2375 0, /* tp_call */
2376 0, /* tp_str */
2377 0, /* tp_getattro */
2378 0, /* tp_setattro */
2379 0, /* tp_as_buffer */
2380 Py_TPFLAGS_DEFAULT, /* tp_flags */
2381 kqueue_event_doc, /* tp_doc */
2382 0, /* tp_traverse */
2383 0, /* tp_clear */
2384 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
2385 0, /* tp_weaklistoffset */
2386 0, /* tp_iter */
2387 0, /* tp_iternext */
2388 0, /* tp_methods */
2389 kqueue_event_members, /* tp_members */
2390 0, /* tp_getset */
2391 0, /* tp_base */
2392 0, /* tp_dict */
2393 0, /* tp_descr_get */
2394 0, /* tp_descr_set */
2395 0, /* tp_dictoffset */
2396 (initproc)kqueue_event_init, /* tp_init */
2397 0, /* tp_alloc */
2398 0, /* tp_new */
2399 0, /* tp_free */
2400};
2401
2402static PyMethodDef kqueue_queue_methods[] = {
2403 SELECT_KQUEUE_FROMFD_METHODDEF
2404 SELECT_KQUEUE_CLOSE_METHODDEF
2405 SELECT_KQUEUE_FILENO_METHODDEF
2406 SELECT_KQUEUE_CONTROL_METHODDEF
2407 {NULL, NULL},
2408};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002409
2410static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyVarObject_HEAD_INIT(NULL, 0)
2412 "select.kqueue", /* tp_name */
2413 sizeof(kqueue_queue_Object), /* tp_basicsize */
2414 0, /* tp_itemsize */
2415 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002416 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 0, /* tp_getattr */
2418 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002419 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 0, /* tp_repr */
2421 0, /* tp_as_number */
2422 0, /* tp_as_sequence */
2423 0, /* tp_as_mapping */
2424 0, /* tp_hash */
2425 0, /* tp_call */
2426 0, /* tp_str */
2427 0, /* tp_getattro */
2428 0, /* tp_setattro */
2429 0, /* tp_as_buffer */
2430 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tal Einat6dc57e22018-06-30 23:02:48 +03002431 select_kqueue__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 0, /* tp_traverse */
2433 0, /* tp_clear */
2434 0, /* tp_richcompare */
2435 0, /* tp_weaklistoffset */
2436 0, /* tp_iter */
2437 0, /* tp_iternext */
2438 kqueue_queue_methods, /* tp_methods */
2439 0, /* tp_members */
2440 kqueue_queue_getsetlist, /* tp_getset */
2441 0, /* tp_base */
2442 0, /* tp_dict */
2443 0, /* tp_descr_get */
2444 0, /* tp_descr_set */
2445 0, /* tp_dictoffset */
2446 0, /* tp_init */
2447 0, /* tp_alloc */
Tal Einat6dc57e22018-06-30 23:02:48 +03002448 select_kqueue, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002450};
2451
2452#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002453
2454
2455
2456
2457
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002458/* ************************************************************************ */
2459
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002460
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002461static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002462 SELECT_SELECT_METHODDEF
2463 SELECT_POLL_METHODDEF
2464 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002466};
2467
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002468PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002469"This module supports asynchronous I/O on multiple file descriptors.\n\
2470\n\
2471*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002472On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002473
Martin v. Löwis1a214512008-06-11 05:26:20 +00002474
2475static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 PyModuleDef_HEAD_INIT,
2477 "select",
2478 module_doc,
2479 -1,
2480 select_methods,
2481 NULL,
2482 NULL,
2483 NULL,
2484 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002485};
2486
Jesus Cead8b9ae62011-11-14 19:07:41 +01002487
2488
2489
Mark Hammond62b1ab12002-07-23 06:31:15 +00002490PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002491PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002492{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 PyObject *m;
2494 m = PyModule_Create(&selectmodule);
2495 if (m == NULL)
2496 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002497
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002498 Py_INCREF(PyExc_OSError);
2499 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002500
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002501#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002502#ifdef HAVE_BROKEN_PIPE_BUF
2503#undef PIPE_BUF
2504#define PIPE_BUF 512
2505#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002506 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002507#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002508
Charles-François Natali986a56c2013-01-19 12:19:10 +01002509#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002510#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 if (select_have_broken_poll()) {
2512 if (PyObject_DelAttrString(m, "poll") == -1) {
2513 PyErr_Clear();
2514 }
2515 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002516#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002518#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 if (PyType_Ready(&poll_Type) < 0)
2520 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002521 PyModule_AddIntMacro(m, POLLIN);
2522 PyModule_AddIntMacro(m, POLLPRI);
2523 PyModule_AddIntMacro(m, POLLOUT);
2524 PyModule_AddIntMacro(m, POLLERR);
2525 PyModule_AddIntMacro(m, POLLHUP);
2526 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002527
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002528#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002529 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002530#endif
2531#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002532 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002533#endif
2534#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002535 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002536#endif
2537#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002538 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002539#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002540#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002541 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002542#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002543#ifdef POLLRDHUP
2544 /* Kernel 2.6.17+ */
2545 PyModule_AddIntMacro(m, POLLRDHUP);
2546#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002548#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002549
Jesus Cead8b9ae62011-11-14 19:07:41 +01002550#ifdef HAVE_SYS_DEVPOLL_H
2551 if (PyType_Ready(&devpoll_Type) < 0)
2552 return NULL;
2553#endif
2554
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002555#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2557 if (PyType_Ready(&pyEpoll_Type) < 0)
2558 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 Py_INCREF(&pyEpoll_Type);
2561 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002562
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002563 PyModule_AddIntMacro(m, EPOLLIN);
2564 PyModule_AddIntMacro(m, EPOLLOUT);
2565 PyModule_AddIntMacro(m, EPOLLPRI);
2566 PyModule_AddIntMacro(m, EPOLLERR);
2567 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002568#ifdef EPOLLRDHUP
2569 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002570 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002571#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002572 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002573#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002575 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002576#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002577#ifdef EPOLLEXCLUSIVE
2578 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2579#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002580
2581#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002582 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002583#endif
2584#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002585 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002586#endif
2587#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002588 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002589#endif
2590#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002591 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002592#endif
2593#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002594 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002595#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002596
Benjamin Peterson95c16622011-12-27 15:36:32 -06002597#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002598 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002599#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002600#endif /* HAVE_EPOLL */
2601
2602#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002603 kqueue_event_Type.tp_new = PyType_GenericNew;
2604 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2605 if(PyType_Ready(&kqueue_event_Type) < 0)
2606 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 Py_INCREF(&kqueue_event_Type);
2609 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2612 if(PyType_Ready(&kqueue_queue_Type) < 0)
2613 return NULL;
2614 Py_INCREF(&kqueue_queue_Type);
2615 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2616
2617 /* event filters */
2618 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2619 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002622#endif
2623#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002625#endif
2626#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002628#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002629#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002631#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002632#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002634#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 /* event flags */
2638 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2639 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2640 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2641 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2642 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2643 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002644
Berker Peksag7ec64562016-09-14 18:16:59 +03002645#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002647#endif
2648#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002650#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2653 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002656#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002658#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002660 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002661#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2663 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2664 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2665 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2666 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2667 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2668 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002669#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002672#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2674 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2675 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2676 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2677 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2680 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2681 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002682#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002683
2684 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002685#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2687 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2688 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002689#endif
2690
2691#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002693}