blob: fe69cd58dc6a28ea43fbdef6fcb2d654263be2e5 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Berker Peksagfe8d9662016-07-19 21:09:26 +03007#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
8#define _GNU_SOURCE
9#endif
10
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000011#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +000012#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000013
Jesus Cead8b9ae62011-11-14 19:07:41 +010014#ifdef HAVE_SYS_DEVPOLL_H
15#include <sys/resource.h>
16#include <sys/devpoll.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#endif
21
Thomas Wouters477c8d52006-05-27 19:21:47 +000022#ifdef __APPLE__
23 /* Perform runtime testing for a broken poll on OSX to make it easier
24 * to use the same binary on multiple releases of the OS.
25 */
26#undef HAVE_BROKEN_POLL
27#endif
28
Tim Petersd92dfe02000-12-12 01:18:41 +000029/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
30 64 is too small (too many people have bumped into that limit).
31 Here we boost it.
32 Users who want even more than the boosted limit should #define
33 FD_SETSIZE higher before this; e.g., via compiler /D switch.
34*/
35#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
36#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000038
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000039#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000040#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000041#elif defined(HAVE_SYS_POLL_H)
42#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000043#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000044
Guido van Rossum37273171996-12-09 18:47:43 +000045#ifdef __sgi
46/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000047extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000048#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000052#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053
Guido van Rossum6f489d91996-06-28 20:15:15 +000054#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000055# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000057#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000059#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000060
Tal Einat6dc57e22018-06-30 23:02:48 +030061/*[clinic input]
62module select
63class select.poll "pollObject *" "&poll_Type"
64class select.devpoll "devpollObject *" "&devpoll_Type"
65class select.epoll "pyEpoll_Object *" "&pyEpoll_Type"
66class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type"
67[clinic start generated code]*/
68/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/
69
70static int
71fildes_converter(PyObject *o, void *p)
72{
73 int fd;
74 int *pointer = (int *)p;
75 fd = PyObject_AsFileDescriptor(o);
76 if (fd == -1)
77 return 0;
78 *pointer = fd;
79 return 1;
80}
81
82/*[python input]
83class fildes_converter(CConverter):
84 type = 'int'
85 converter = 'fildes_converter'
86[python start generated code]*/
87/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/
88
Barry Warsawc1cb3601996-12-12 22:16:21 +000089/* list of Python objects and their file descriptor */
90typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 PyObject *obj; /* owned reference */
92 SOCKET fd;
93 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000094} pylist;
95
Barry Warsawc1cb3601996-12-12 22:16:21 +000096static void
Tim Peters4b046c22001-08-16 21:59:46 +000097reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000098{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020099 unsigned int i;
100 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200101 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 }
103 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104}
105
106
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000107/* returns -1 and sets the Python exception if an error occurred, otherwise
108 returns a number >= 0
109*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000110static int
Brett Cannon62dba4c2003-09-10 19:37:42 +0000111seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200114 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100115 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 PyObject* fast_seq = NULL;
117 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +0000118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
120 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Benjamin Petersone0edb8b2010-06-27 23:49:45 +0000122 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (!fast_seq)
124 return -1;
125
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100126 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 SOCKET v;
128
129 /* any intervening fileno() calls could decr this refcnt */
130 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200131 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 Py_INCREF(o);
134 v = PyObject_AsFileDescriptor( o );
135 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000136
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000137#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000139#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200140 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 PyErr_SetString(PyExc_ValueError,
142 "filedescriptor out of range in select()");
143 goto finally;
144 }
145 if (v > max)
146 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000147#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200151 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 PyErr_SetString(PyExc_ValueError,
153 "too many file descriptors in select()");
154 goto finally;
155 }
156 fd2obj[index].obj = o;
157 fd2obj[index].fd = v;
158 fd2obj[index].sentinel = 0;
159 fd2obj[++index].sentinel = -1;
160 }
161 Py_DECREF(fast_seq);
162 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000163
164 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 Py_XDECREF(o);
166 Py_DECREF(fast_seq);
167 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000168}
169
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000170/* returns NULL and sets the Python exception if an error occurred */
171static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000172set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 int i, j, count=0;
175 PyObject *list, *o;
176 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
179 if (FD_ISSET(fd2obj[j].fd, set))
180 count++;
181 }
182 list = PyList_New(count);
183 if (!list)
184 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 i = 0;
187 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
188 fd = fd2obj[j].fd;
189 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 o = fd2obj[j].obj;
191 fd2obj[j].obj = NULL;
192 /* transfer ownership */
193 if (PyList_SetItem(list, i, o) < 0)
194 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 i++;
197 }
198 }
199 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000200 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 Py_DECREF(list);
202 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000203}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000204
Barry Warsawb44740f2001-08-16 16:52:59 +0000205#undef SELECT_USES_HEAP
206#if FD_SETSIZE > 1024
207#define SELECT_USES_HEAP
208#endif /* FD_SETSIZE > 1024 */
209
Tal Einat6dc57e22018-06-30 23:02:48 +0300210/*[clinic input]
211select.select
212
213 rlist: object
214 wlist: object
215 xlist: object
216 timeout as timeout_obj: object = None
217 /
218
219Wait until one or more file descriptors are ready for some kind of I/O.
220
221The first three arguments are sequences of file descriptors to be waited for:
222rlist -- wait until ready for reading
223wlist -- wait until ready for writing
224xlist -- wait for an "exceptional condition"
225If only one kind of condition is required, pass [] for the other lists.
226
227A file descriptor is either a socket or file object, or a small integer
228gotten from a fileno() method call on one of those.
229
230The optional 4th argument specifies a timeout in seconds; it may be
231a floating point number to specify fractions of seconds. If it is absent
232or None, the call will never time out.
233
234The return value is a tuple of three lists corresponding to the first three
235arguments; each contains the subset of the corresponding file descriptors
236that are ready.
237
238*** IMPORTANT NOTICE ***
239On Windows, only sockets are supported; on Unix, all file
240descriptors can be used.
241[clinic start generated code]*/
242
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000243static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300244select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
245 PyObject *xlist, PyObject *timeout_obj)
246/*[clinic end generated code: output=2b3cfa824f7ae4cf input=177e72184352df25]*/
Guido van Rossumed233a51992-06-23 09:07:03 +0000247{
Barry Warsawb44740f2001-08-16 16:52:59 +0000248#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 /* XXX: All this should probably be implemented as follows:
252 * - find the highest descriptor we're interested in
253 * - add one
254 * - that's the size
255 * See: Stevens, APitUE, $12.5.1
256 */
257 pylist rfd2obj[FD_SETSIZE + 1];
258 pylist wfd2obj[FD_SETSIZE + 1];
259 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000260#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 PyObject *ret = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 int imax, omax, emax, max;
265 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200266 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000267
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200268 if (timeout_obj == Py_None)
269 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200271 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100272 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200273 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
274 PyErr_SetString(PyExc_TypeError,
275 "timeout must be a float or None");
276 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100277 return NULL;
278 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100279
Pablo Galindo2c15b292017-10-17 15:14:41 +0100280 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100281 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100282 if (tv.tv_sec < 0) {
283 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 return NULL;
285 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 tvp = &tv;
287 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000288
Barry Warsawb44740f2001-08-16 16:52:59 +0000289#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 /* Allocate memory for the lists */
291 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
292 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
293 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
294 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
295 if (rfd2obj) PyMem_DEL(rfd2obj);
296 if (wfd2obj) PyMem_DEL(wfd2obj);
297 if (efd2obj) PyMem_DEL(efd2obj);
298 return PyErr_NoMemory();
299 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000300#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 /* Convert sequences to fd_sets, and get maximum fd number
303 * propagates the Python exception set in seq2set()
304 */
305 rfd2obj[0].sentinel = -1;
306 wfd2obj[0].sentinel = -1;
307 efd2obj[0].sentinel = -1;
Tal Einat6dc57e22018-06-30 23:02:48 +0300308 if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300310 if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300312 if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 max = imax;
316 if (omax > max) max = omax;
317 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000318
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200319 if (tvp)
320 deadline = _PyTime_GetMonotonicClock() + timeout;
321
322 do {
323 Py_BEGIN_ALLOW_THREADS
324 errno = 0;
325 n = select(max, &ifdset, &ofdset, &efdset, tvp);
326 Py_END_ALLOW_THREADS
327
328 if (errno != EINTR)
329 break;
330
331 /* select() was interrupted by a signal */
332 if (PyErr_CheckSignals())
333 goto finally;
334
335 if (tvp) {
336 timeout = deadline - _PyTime_GetMonotonicClock();
337 if (timeout < 0) {
Oran Avraham7f524152018-12-05 22:36:03 +0200338 /* bpo-35310: lists were unmodified -- clear them explicitly */
339 FD_ZERO(&ifdset);
340 FD_ZERO(&ofdset);
341 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200342 n = 0;
343 break;
344 }
345 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200346 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200347 }
348 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000349
Thomas Heller106f4c72002-09-24 16:51:00 +0000350#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200352 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000354#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200356 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000358#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 else {
360 /* any of these three calls can raise an exception. it's more
361 convenient to test for this after all three calls... but
362 is that acceptable?
363 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300364 rlist = set2list(&ifdset, rfd2obj);
365 wlist = set2list(&ofdset, wfd2obj);
366 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (PyErr_Occurred())
368 ret = NULL;
369 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300370 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000371
Tal Einat6dc57e22018-06-30 23:02:48 +0300372 Py_XDECREF(rlist);
373 Py_XDECREF(wlist);
374 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 }
376
Barry Warsawc1cb3601996-12-12 22:16:21 +0000377 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 reap_obj(rfd2obj);
379 reap_obj(wfd2obj);
380 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000381#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 PyMem_DEL(rfd2obj);
383 PyMem_DEL(wfd2obj);
384 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000385#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000387}
388
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000389#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000391 * poll() support
392 */
393
394typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 PyObject_HEAD
396 PyObject *dict;
397 int ufd_uptodate;
398 int ufd_len;
399 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300400 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401} pollObject;
402
Jeremy Hylton938ace62002-07-17 16:30:39 +0000403static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406 contained within a pollObject. Return 1 on success, 0 on an error.
407*/
408
409static int
410update_ufd_array(pollObject *self)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 Py_ssize_t i, pos;
413 PyObject *key, *value;
414 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000415
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200416 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
418 if (self->ufds == NULL) {
419 self->ufds = old_ufds;
420 PyErr_NoMemory();
421 return 0;
422 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 i = pos = 0;
425 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200426 assert(i < self->ufd_len);
427 /* Never overflow */
428 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200429 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 i++;
431 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200432 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 self->ufd_uptodate = 1;
434 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Tal Einat6dc57e22018-06-30 23:02:48 +0300437/*[clinic input]
438select.poll.register
439
440 fd: fildes
441 either an integer, or an object with a fileno() method returning an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300442 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300443 an optional bitmask describing the type of events to check for
444 /
445
446Register a file descriptor with the polling object.
447[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448
449static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300450select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300451/*[clinic end generated code: output=0dc7173c800a4a65 input=f18711d9bb021e25]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452{
Tal Einat6dc57e22018-06-30 23:02:48 +0300453 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 /* Add entry to the internal dictionary: the key is the
457 file descriptor, and the value is the event mask. */
458 key = PyLong_FromLong(fd);
459 if (key == NULL)
460 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300461 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 if (value == NULL) {
463 Py_DECREF(key);
464 return NULL;
465 }
466 err = PyDict_SetItem(self->dict, key, value);
467 Py_DECREF(key);
468 Py_DECREF(value);
469 if (err < 0)
470 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 self->ufd_uptodate = 0;
473
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200474 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475}
476
Tal Einat6dc57e22018-06-30 23:02:48 +0300477
478/*[clinic input]
479select.poll.modify
480
481 fd: fildes
482 either an integer, or an object with a fileno() method returning
483 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300484 eventmask: unsigned_short
Tal Einat6dc57e22018-06-30 23:02:48 +0300485 a bitmask describing the type of events to check for
486 /
487
488Modify an already registered file descriptor.
489[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000490
491static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300492select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300493/*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000494{
Tal Einat6dc57e22018-06-30 23:02:48 +0300495 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Modify registered fd */
499 key = PyLong_FromLong(fd);
500 if (key == NULL)
501 return NULL;
502 if (PyDict_GetItem(self->dict, key) == NULL) {
503 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200504 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200505 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 return NULL;
507 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300508 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (value == NULL) {
510 Py_DECREF(key);
511 return NULL;
512 }
513 err = PyDict_SetItem(self->dict, key, value);
514 Py_DECREF(key);
515 Py_DECREF(value);
516 if (err < 0)
517 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 self->ufd_uptodate = 0;
520
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200521 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000522}
523
524
Tal Einat6dc57e22018-06-30 23:02:48 +0300525/*[clinic input]
526select.poll.unregister
527
528 fd: fildes
529 /
530
531Remove a file descriptor being tracked by the polling object.
532[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533
534static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300535select_poll_unregister_impl(pollObject *self, int fd)
536/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 /* Check whether the fd is already in the array */
541 key = PyLong_FromLong(fd);
542 if (key == NULL)
543 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 if (PyDict_DelItem(self->dict, key) == -1) {
546 Py_DECREF(key);
547 /* This will simply raise the KeyError set by PyDict_DelItem
548 if the file descriptor isn't registered. */
549 return NULL;
550 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 Py_DECREF(key);
553 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000554
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200555 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556}
557
Tal Einat6dc57e22018-06-30 23:02:48 +0300558/*[clinic input]
559select.poll.poll
560
561 timeout as timeout_obj: object = None
562 /
563
564Polls the set of registered file descriptors.
565
566Returns a list containing any descriptors that have events or errors to
567report, as a list of (fd, event) 2-tuples.
568[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000569
570static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300571select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
572/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000573{
Tal Einat6dc57e22018-06-30 23:02:48 +0300574 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200575 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200577 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200578 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000579
Tal Einat6dc57e22018-06-30 23:02:48 +0300580 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200581 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100582 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
584 PyErr_SetString(PyExc_TypeError,
585 "timeout must be an integer or None");
586 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200588 }
589
Pablo Galindo2c15b292017-10-17 15:14:41 +0100590 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200591 if (ms < INT_MIN || ms > INT_MAX) {
592 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200594 }
595
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200596 if (timeout >= 0) {
597 deadline = _PyTime_GetMonotonicClock() + timeout;
598 }
599 }
600
601 /* On some OSes, typically BSD-based ones, the timeout parameter of the
602 poll() syscall, when negative, must be exactly INFTIM, where defined,
603 or -1. See issue 31334. */
604 if (ms < 0) {
605#ifdef INFTIM
606 ms = INFTIM;
607#else
608 ms = -1;
609#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000611
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300612 /* Avoid concurrent poll() invocation, issue 8865 */
613 if (self->poll_running) {
614 PyErr_SetString(PyExc_RuntimeError,
615 "concurrent poll() invocation");
616 return NULL;
617 }
618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 /* Ensure the ufd array is up to date */
620 if (!self->ufd_uptodate)
621 if (update_ufd_array(self) == 0)
622 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000623
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300624 self->poll_running = 1;
625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200627 async_err = 0;
628 do {
629 Py_BEGIN_ALLOW_THREADS
630 errno = 0;
631 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
632 Py_END_ALLOW_THREADS
633
634 if (errno != EINTR)
635 break;
636
637 /* poll() was interrupted by a signal */
638 if (PyErr_CheckSignals()) {
639 async_err = 1;
640 break;
641 }
642
643 if (timeout >= 0) {
644 timeout = deadline - _PyTime_GetMonotonicClock();
645 if (timeout < 0) {
646 poll_result = 0;
647 break;
648 }
649 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
650 /* retry poll() with the recomputed timeout */
651 }
652 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000653
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300654 self->poll_running = 0;
655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200657 if (!async_err)
658 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 return NULL;
660 }
661
662 /* build the result list */
663
664 result_list = PyList_New(poll_result);
665 if (!result_list)
666 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200668 for (i = 0, j = 0; j < poll_result; j++) {
669 /* skip to the next fired descriptor */
670 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 i++;
672 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200673 /* if we hit a NULL return, set value to NULL
674 and break out of loop; code at end will
675 clean up result_list */
676 value = PyTuple_New(2);
677 if (value == NULL)
678 goto error;
679 num = PyLong_FromLong(self->ufds[i].fd);
680 if (num == NULL) {
681 Py_DECREF(value);
682 goto error;
683 }
684 PyTuple_SET_ITEM(value, 0, num);
685
686 /* The &0xffff is a workaround for AIX. 'revents'
687 is a 16-bit short, and IBM assigned POLLNVAL
688 to be 0x8000, so the conversion to int results
689 in a negative number. See SF bug #923315. */
690 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
691 if (num == NULL) {
692 Py_DECREF(value);
693 goto error;
694 }
695 PyTuple_SET_ITEM(value, 1, num);
696 if ((PyList_SetItem(result_list, j, value)) == -1) {
697 Py_DECREF(value);
698 goto error;
699 }
700 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 }
702 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000703
704 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 Py_DECREF(result_list);
706 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000707}
708
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000709static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000710newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 pollObject *self;
713 self = PyObject_New(pollObject, &poll_Type);
714 if (self == NULL)
715 return NULL;
716 /* ufd_uptodate is a Boolean, denoting whether the
717 array pointed to by ufds matches the contents of the dictionary. */
718 self->ufd_uptodate = 0;
719 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300720 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 self->dict = PyDict_New();
722 if (self->dict == NULL) {
723 Py_DECREF(self);
724 return NULL;
725 }
726 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000727}
728
729static void
730poll_dealloc(pollObject *self)
731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 if (self->ufds != NULL)
733 PyMem_DEL(self->ufds);
734 Py_XDECREF(self->dict);
735 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000736}
737
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000738
Jesus Cead8b9ae62011-11-14 19:07:41 +0100739#ifdef HAVE_SYS_DEVPOLL_H
740typedef struct {
741 PyObject_HEAD
742 int fd_devpoll;
743 int max_n_fds;
744 int n_fds;
745 struct pollfd *fds;
746} devpollObject;
747
748static PyTypeObject devpoll_Type;
749
Victor Stinner13423c32013-08-22 00:19:50 +0200750static PyObject *
751devpoll_err_closed(void)
752{
753 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
754 return NULL;
755}
756
Jesus Cead8b9ae62011-11-14 19:07:41 +0100757static int devpoll_flush(devpollObject *self)
758{
759 int size, n;
760
761 if (!self->n_fds) return 0;
762
763 size = sizeof(struct pollfd)*self->n_fds;
764 self->n_fds = 0;
765
Victor Stinner54799672015-03-19 23:33:09 +0100766 n = _Py_write(self->fd_devpoll, self->fds, size);
767 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100768 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100769
Jesus Cead8b9ae62011-11-14 19:07:41 +0100770 if (n < size) {
771 /*
772 ** Data writed to /dev/poll is a binary data structure. It is not
773 ** clear what to do if a partial write occurred. For now, raise
774 ** an exception and see if we actually found this problem in
775 ** the wild.
776 ** See http://bugs.python.org/issue6397.
777 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300778 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100779 "Please, report at http://bugs.python.org/. "
780 "Data to report: Size tried: %d, actual size written: %d.",
781 size, n);
782 return -1;
783 }
784 return 0;
785}
786
787static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300788internal_devpoll_register(devpollObject *self, int fd,
789 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100790{
Victor Stinner13423c32013-08-22 00:19:50 +0200791 if (self->fd_devpoll < 0)
792 return devpoll_err_closed();
793
Jesus Cead8b9ae62011-11-14 19:07:41 +0100794 if (remove) {
795 self->fds[self->n_fds].fd = fd;
796 self->fds[self->n_fds].events = POLLREMOVE;
797
798 if (++self->n_fds == self->max_n_fds) {
799 if (devpoll_flush(self))
800 return NULL;
801 }
802 }
803
804 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200805 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100806
807 if (++self->n_fds == self->max_n_fds) {
808 if (devpoll_flush(self))
809 return NULL;
810 }
811
812 Py_RETURN_NONE;
813}
814
Tal Einat6dc57e22018-06-30 23:02:48 +0300815/*[clinic input]
816select.devpoll.register
817
818 fd: fildes
819 either an integer, or an object with a fileno() method returning
820 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300821 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300822 an optional bitmask describing the type of events to check for
823 /
824
825Register a file descriptor with the polling object.
826[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100827
828static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300829select_devpoll_register_impl(devpollObject *self, int fd,
830 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300831/*[clinic end generated code: output=6e07fe8b74abba0c input=5bd7cacc47a8ee46]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100832{
Tal Einat6dc57e22018-06-30 23:02:48 +0300833 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100834}
835
Tal Einat6dc57e22018-06-30 23:02:48 +0300836/*[clinic input]
837select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100838
Tal Einat6dc57e22018-06-30 23:02:48 +0300839 fd: fildes
840 either an integer, or an object with a fileno() method returning
841 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300842 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300843 an optional bitmask describing the type of events to check for
844 /
845
846Modify a possible already registered file descriptor.
847[clinic start generated code]*/
848
849static PyObject *
850select_devpoll_modify_impl(devpollObject *self, int fd,
851 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300852/*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100853{
Tal Einat6dc57e22018-06-30 23:02:48 +0300854 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100855}
856
Tal Einat6dc57e22018-06-30 23:02:48 +0300857/*[clinic input]
858select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859
Tal Einat6dc57e22018-06-30 23:02:48 +0300860 fd: fildes
861 /
862
863Remove a file descriptor being tracked by the polling object.
864[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100865
866static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300867select_devpoll_unregister_impl(devpollObject *self, int fd)
868/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100869{
Victor Stinner13423c32013-08-22 00:19:50 +0200870 if (self->fd_devpoll < 0)
871 return devpoll_err_closed();
872
Jesus Cead8b9ae62011-11-14 19:07:41 +0100873 self->fds[self->n_fds].fd = fd;
874 self->fds[self->n_fds].events = POLLREMOVE;
875
876 if (++self->n_fds == self->max_n_fds) {
877 if (devpoll_flush(self))
878 return NULL;
879 }
880
881 Py_RETURN_NONE;
882}
883
Tal Einat6dc57e22018-06-30 23:02:48 +0300884/*[clinic input]
885select.devpoll.poll
886 timeout as timeout_obj: object = None
887 /
888
889Polls the set of registered file descriptors.
890
891Returns a list containing any descriptors that have events or errors to
892report, as a list of (fd, event) 2-tuples.
893[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100894
895static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300896select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
897/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100898{
899 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200900 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100901 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200903 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100904
Victor Stinner13423c32013-08-22 00:19:50 +0200905 if (self->fd_devpoll < 0)
906 return devpoll_err_closed();
907
Jesus Cead8b9ae62011-11-14 19:07:41 +0100908 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300909 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100910 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200911 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 }
913 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200914 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100915 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200916 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
917 PyErr_SetString(PyExc_TypeError,
918 "timeout must be an integer or None");
919 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200921 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100922
Pablo Galindo2c15b292017-10-17 15:14:41 +0100923 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200924 if (ms < -1 || ms > INT_MAX) {
925 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
926 return NULL;
927 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928 }
929
930 if (devpoll_flush(self))
931 return NULL;
932
933 dvp.dp_fds = self->fds;
934 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200935 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100936
Victor Stinner45ca48b2015-03-31 12:10:33 +0200937 if (timeout >= 0)
938 deadline = _PyTime_GetMonotonicClock() + timeout;
939
940 do {
941 /* call devpoll() */
942 Py_BEGIN_ALLOW_THREADS
943 errno = 0;
944 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
945 Py_END_ALLOW_THREADS
946
947 if (errno != EINTR)
948 break;
949
950 /* devpoll() was interrupted by a signal */
951 if (PyErr_CheckSignals())
952 return NULL;
953
954 if (timeout >= 0) {
955 timeout = deadline - _PyTime_GetMonotonicClock();
956 if (timeout < 0) {
957 poll_result = 0;
958 break;
959 }
960 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
961 dvp.dp_timeout = (int)ms;
962 /* retry devpoll() with the recomputed timeout */
963 }
964 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100965
966 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300967 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100968 return NULL;
969 }
970
971 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100972 result_list = PyList_New(poll_result);
973 if (!result_list)
974 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200975
976 for (i = 0; i < poll_result; i++) {
977 num1 = PyLong_FromLong(self->fds[i].fd);
978 num2 = PyLong_FromLong(self->fds[i].revents);
979 if ((num1 == NULL) || (num2 == NULL)) {
980 Py_XDECREF(num1);
981 Py_XDECREF(num2);
982 goto error;
983 }
984 value = PyTuple_Pack(2, num1, num2);
985 Py_DECREF(num1);
986 Py_DECREF(num2);
987 if (value == NULL)
988 goto error;
989 if ((PyList_SetItem(result_list, i, value)) == -1) {
990 Py_DECREF(value);
991 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100992 }
993 }
994
995 return result_list;
996
997 error:
998 Py_DECREF(result_list);
999 return NULL;
1000}
1001
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001002static int
1003devpoll_internal_close(devpollObject *self)
1004{
1005 int save_errno = 0;
1006 if (self->fd_devpoll >= 0) {
1007 int fd = self->fd_devpoll;
1008 self->fd_devpoll = -1;
1009 Py_BEGIN_ALLOW_THREADS
1010 if (close(fd) < 0)
1011 save_errno = errno;
1012 Py_END_ALLOW_THREADS
1013 }
1014 return save_errno;
1015}
1016
Tal Einat6dc57e22018-06-30 23:02:48 +03001017/*[clinic input]
1018select.devpoll.close
1019
1020Close the devpoll file descriptor.
1021
1022Further operations on the devpoll object will raise an exception.
1023[clinic start generated code]*/
1024
1025static PyObject *
1026select_devpoll_close_impl(devpollObject *self)
1027/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001028{
1029 errno = devpoll_internal_close(self);
1030 if (errno < 0) {
1031 PyErr_SetFromErrno(PyExc_OSError);
1032 return NULL;
1033 }
1034 Py_RETURN_NONE;
1035}
1036
Victor Stinner13423c32013-08-22 00:19:50 +02001037static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001038devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001039{
1040 if (self->fd_devpoll < 0)
1041 Py_RETURN_TRUE;
1042 else
1043 Py_RETURN_FALSE;
1044}
1045
Tal Einat6dc57e22018-06-30 23:02:48 +03001046/*[clinic input]
1047select.devpoll.fileno
1048
1049Return the file descriptor.
1050[clinic start generated code]*/
1051
1052static PyObject *
1053select_devpoll_fileno_impl(devpollObject *self)
1054/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001055{
1056 if (self->fd_devpoll < 0)
1057 return devpoll_err_closed();
1058 return PyLong_FromLong(self->fd_devpoll);
1059}
1060
Victor Stinner13423c32013-08-22 00:19:50 +02001061static PyGetSetDef devpoll_getsetlist[] = {
1062 {"closed", (getter)devpoll_get_closed, NULL,
1063 "True if the devpoll object is closed"},
1064 {0},
1065};
1066
Jesus Cead8b9ae62011-11-14 19:07:41 +01001067static devpollObject *
1068newDevPollObject(void)
1069{
1070 devpollObject *self;
1071 int fd_devpoll, limit_result;
1072 struct pollfd *fds;
1073 struct rlimit limit;
1074
Jesus Cead8b9ae62011-11-14 19:07:41 +01001075 /*
1076 ** If we try to process more that getrlimit()
1077 ** fds, the kernel will give an error, so
1078 ** we set the limit here. It is a dynamic
1079 ** value, because we can change rlimit() anytime.
1080 */
1081 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001082 if (limit_result == -1) {
1083 PyErr_SetFromErrno(PyExc_OSError);
1084 return NULL;
1085 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001086
1087 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1088 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001089 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090
1091 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1092 if (fds == NULL) {
1093 close(fd_devpoll);
1094 PyErr_NoMemory();
1095 return NULL;
1096 }
1097
1098 self = PyObject_New(devpollObject, &devpoll_Type);
1099 if (self == NULL) {
1100 close(fd_devpoll);
1101 PyMem_DEL(fds);
1102 return NULL;
1103 }
1104 self->fd_devpoll = fd_devpoll;
1105 self->max_n_fds = limit.rlim_cur;
1106 self->n_fds = 0;
1107 self->fds = fds;
1108
1109 return self;
1110}
1111
1112static void
1113devpoll_dealloc(devpollObject *self)
1114{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001115 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001116 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001117 PyObject_Del(self);
1118}
1119
Jesus Cead8b9ae62011-11-14 19:07:41 +01001120#endif /* HAVE_SYS_DEVPOLL_H */
1121
1122
Tal Einat6dc57e22018-06-30 23:02:48 +03001123/*[clinic input]
1124select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001125
Tal Einat6dc57e22018-06-30 23:02:48 +03001126Returns a polling object.
1127
1128This object supports registering and unregistering file descriptors, and then
1129polling them for I/O events.
1130[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001131
1132static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001133select_poll_impl(PyObject *module)
1134/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001137}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138
Jesus Cead8b9ae62011-11-14 19:07:41 +01001139#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001140
1141/*[clinic input]
1142select.devpoll
1143
1144Returns a polling object.
1145
1146This object supports registering and unregistering file descriptors, and then
1147polling them for I/O events.
1148[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001149
1150static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001151select_devpoll_impl(PyObject *module)
1152/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001153{
1154 return (PyObject *)newDevPollObject();
1155}
1156#endif
1157
1158
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001161 * On some systems poll() sets errno on invalid file descriptors. We test
1162 * for this at runtime because this bug may be fixed or introduced between
1163 * OS releases.
1164 */
1165static int select_have_broken_poll(void)
1166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 int poll_test;
1168 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 /* Create a file descriptor to make invalid */
1173 if (pipe(filedes) < 0) {
1174 return 1;
1175 }
1176 poll_struct.fd = filedes[0];
1177 close(filedes[0]);
1178 close(filedes[1]);
1179 poll_test = poll(&poll_struct, 1, 0);
1180 if (poll_test < 0) {
1181 return 1;
1182 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1183 return 1;
1184 }
1185 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001186}
1187#endif /* __APPLE__ */
1188
1189#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001190
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001191#ifdef HAVE_EPOLL
1192/* **************************************************************************
1193 * epoll interface for Linux 2.6
1194 *
1195 * Written by Christian Heimes
1196 * Inspired by Twisted's _epoll.pyx and select.poll()
1197 */
1198
1199#ifdef HAVE_SYS_EPOLL_H
1200#include <sys/epoll.h>
1201#endif
1202
1203typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001205 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001206} pyEpoll_Object;
1207
1208static PyTypeObject pyEpoll_Type;
1209#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1210
1211static PyObject *
1212pyepoll_err_closed(void)
1213{
Victor Stinner13423c32013-08-22 00:19:50 +02001214 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216}
1217
1218static int
1219pyepoll_internal_close(pyEpoll_Object *self)
1220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 int save_errno = 0;
1222 if (self->epfd >= 0) {
1223 int epfd = self->epfd;
1224 self->epfd = -1;
1225 Py_BEGIN_ALLOW_THREADS
1226 if (close(epfd) < 0)
1227 save_errno = errno;
1228 Py_END_ALLOW_THREADS
1229 }
1230 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231}
1232
1233static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001234newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 assert(type != NULL && type->tp_alloc != NULL);
1239 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1240 if (self == NULL)
1241 return NULL;
1242
1243 if (fd == -1) {
1244 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001245#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001246 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1247#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001248 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001249#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 Py_END_ALLOW_THREADS
1251 }
1252 else {
1253 self->epfd = fd;
1254 }
1255 if (self->epfd < 0) {
1256 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001257 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 return NULL;
1259 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001260
1261#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001262 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001263 Py_DECREF(self);
1264 return NULL;
1265 }
1266#endif
1267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001269}
1270
1271
Tal Einat6dc57e22018-06-30 23:02:48 +03001272/*[clinic input]
1273@classmethod
1274select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001275
Tal Einat6dc57e22018-06-30 23:02:48 +03001276 sizehint: int = -1
1277 The expected number of events to be registered. It must be positive,
1278 or -1 to use the default. It is only used on older systems where
1279 epoll_create1() is not available; otherwise it has no effect (though its
1280 value is still checked).
1281 flags: int = 0
1282 Deprecated and completely ignored. However, when supplied, its value
1283 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1284
1285Returns an epolling object.
1286[clinic start generated code]*/
1287
1288static PyObject *
1289select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1290/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1291{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001292 if (sizehint == -1) {
1293 sizehint = FD_SETSIZE - 1;
1294 }
1295 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001296 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001297 return NULL;
1298 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001299
1300#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001301 if (flags && flags != EPOLL_CLOEXEC) {
1302 PyErr_SetString(PyExc_OSError, "invalid flags");
1303 return NULL;
1304 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001305#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001306
Berker Peksage2197d12016-09-26 23:30:41 +03001307 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001308}
1309
1310
1311static void
1312pyepoll_dealloc(pyEpoll_Object *self)
1313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 (void)pyepoll_internal_close(self);
1315 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001316}
1317
Tal Einat6dc57e22018-06-30 23:02:48 +03001318/*[clinic input]
1319select.epoll.close
1320
1321Close the epoll control file descriptor.
1322
1323Further operations on the epoll object will raise an exception.
1324[clinic start generated code]*/
1325
1326static PyObject *
1327select_epoll_close_impl(pyEpoll_Object *self)
1328/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 errno = pyepoll_internal_close(self);
1331 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001332 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 return NULL;
1334 }
1335 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001336}
1337
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001338
1339static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001340pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 if (self->epfd < 0)
1343 Py_RETURN_TRUE;
1344 else
1345 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001346}
1347
Tal Einat6dc57e22018-06-30 23:02:48 +03001348/*[clinic input]
1349select.epoll.fileno
1350
1351Return the epoll control file descriptor.
1352[clinic start generated code]*/
1353
1354static PyObject *
1355select_epoll_fileno_impl(pyEpoll_Object *self)
1356/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 if (self->epfd < 0)
1359 return pyepoll_err_closed();
1360 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361}
1362
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363
Tal Einat6dc57e22018-06-30 23:02:48 +03001364/*[clinic input]
1365@classmethod
1366select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001367
Tal Einat6dc57e22018-06-30 23:02:48 +03001368 fd: int
1369 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370
Tal Einat6dc57e22018-06-30 23:02:48 +03001371Create an epoll object from a given control fd.
1372[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001373
1374static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001375select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1376/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1377{
1378 SOCKET s_fd = (SOCKET)fd;
1379 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1380}
1381
1382
1383static PyObject *
1384pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 struct epoll_event ev;
1387 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 if (epfd < 0)
1390 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001391
Guido van Rossumee07b942013-12-06 17:46:22 -08001392 switch (op) {
1393 case EPOLL_CTL_ADD:
1394 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 ev.events = events;
1396 ev.data.fd = fd;
1397 Py_BEGIN_ALLOW_THREADS
1398 result = epoll_ctl(epfd, op, fd, &ev);
1399 Py_END_ALLOW_THREADS
1400 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001401 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1403 * operation required a non-NULL pointer in event, even
1404 * though this argument is ignored. */
1405 Py_BEGIN_ALLOW_THREADS
1406 result = epoll_ctl(epfd, op, fd, &ev);
1407 if (errno == EBADF) {
1408 /* fd already closed */
1409 result = 0;
1410 errno = 0;
1411 }
1412 Py_END_ALLOW_THREADS
1413 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001414 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 result = -1;
1416 errno = EINVAL;
1417 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001420 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 return NULL;
1422 }
1423 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001424}
1425
Tal Einat6dc57e22018-06-30 23:02:48 +03001426/*[clinic input]
1427select.epoll.register
1428
1429 fd: fildes
1430 the target file descriptor of the operation
1431 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1432 a bit set composed of the various EPOLL constants
1433
1434Registers a new fd or raises an OSError if the fd is already registered.
1435
1436The epoll interface supports all file descriptors that support poll.
1437[clinic start generated code]*/
1438
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001440select_epoll_register_impl(pyEpoll_Object *self, int fd,
1441 unsigned int eventmask)
1442/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001443{
Tal Einat6dc57e22018-06-30 23:02:48 +03001444 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001445}
1446
Tal Einat6dc57e22018-06-30 23:02:48 +03001447/*[clinic input]
1448select.epoll.modify
1449
1450 fd: fildes
1451 the target file descriptor of the operation
1452 eventmask: unsigned_int(bitwise=True)
1453 a bit set composed of the various EPOLL constants
1454
1455Modify event mask for a registered file descriptor.
1456[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001457
1458static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001459select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1460 unsigned int eventmask)
1461/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001462{
Tal Einat6dc57e22018-06-30 23:02:48 +03001463 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001464}
1465
Tal Einat6dc57e22018-06-30 23:02:48 +03001466/*[clinic input]
1467select.epoll.unregister
1468
1469 fd: fildes
1470 the target file descriptor of the operation
1471
1472Remove a registered file descriptor from the epoll object.
1473[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474
1475static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001476select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1477/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478{
Tal Einat6dc57e22018-06-30 23:02:48 +03001479 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480}
1481
Tal Einat6dc57e22018-06-30 23:02:48 +03001482/*[clinic input]
1483select.epoll.poll
1484
1485 timeout as timeout_obj: object = None
1486 the maximum time to wait in seconds (as float);
1487 a timeout of None or -1 makes poll wait indefinitely
1488 maxevents: int = -1
1489 the maximum number of events returned; -1 means no limit
1490
1491Wait for events on the epoll file descriptor.
1492
1493Returns a list containing any descriptors that have events to report,
1494as a list of (fd, events) 2-tuples.
1495[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001496
1497static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001498select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1499 int maxevents)
1500/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 int nfds, i;
1503 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001504 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001505 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 if (self->epfd < 0)
1508 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509
Berker Peksagb690b9b2018-09-11 20:29:48 +03001510 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001511 /* epoll_wait() has a resolution of 1 millisecond, round towards
1512 infinity to wait at least timeout seconds. */
1513 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001514 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001515 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1516 PyErr_SetString(PyExc_TypeError,
1517 "timeout must be an integer or None");
1518 }
1519 return NULL;
1520 }
1521
1522 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1523 if (ms < INT_MIN || ms > INT_MAX) {
1524 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1525 return NULL;
1526 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001527 /* epoll_wait(2) treats all arbitrary negative numbers the same
1528 for the timeout argument, but -1 is the documented way to block
1529 indefinitely in the epoll_wait(2) documentation, so we set ms
1530 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001531
Berker Peksagb690b9b2018-09-11 20:29:48 +03001532 Note that we didn't use INFTIM here since it's non-standard and
1533 isn't available under Linux. */
1534 if (ms < 0) {
1535 ms = -1;
1536 }
1537
1538 if (timeout >= 0) {
1539 deadline = _PyTime_GetMonotonicClock() + timeout;
1540 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001544 maxevents = FD_SETSIZE-1;
1545 }
1546 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 PyErr_Format(PyExc_ValueError,
1548 "maxevents must be greater than 0, got %d",
1549 maxevents);
1550 return NULL;
1551 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001553 evs = PyMem_New(struct epoll_event, maxevents);
1554 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001555 PyErr_NoMemory();
1556 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001558
Victor Stinner41eba222015-03-30 21:59:21 +02001559 do {
1560 Py_BEGIN_ALLOW_THREADS
1561 errno = 0;
1562 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1563 Py_END_ALLOW_THREADS
1564
1565 if (errno != EINTR)
1566 break;
1567
1568 /* poll() was interrupted by a signal */
1569 if (PyErr_CheckSignals())
1570 goto error;
1571
1572 if (timeout >= 0) {
1573 timeout = deadline - _PyTime_GetMonotonicClock();
1574 if (timeout < 0) {
1575 nfds = 0;
1576 break;
1577 }
1578 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1579 /* retry epoll_wait() with the recomputed timeout */
1580 }
1581 } while(1);
1582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001584 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 goto error;
1586 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 elist = PyList_New(nfds);
1589 if (elist == NULL) {
1590 goto error;
1591 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001594 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (etuple == NULL) {
1596 Py_CLEAR(elist);
1597 goto error;
1598 }
1599 PyList_SET_ITEM(elist, i, etuple);
1600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Christian Heimesf6cd9672008-03-26 13:45:42 +00001602 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001603 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605}
1606
Tal Einat6dc57e22018-06-30 23:02:48 +03001607
1608/*[clinic input]
1609select.epoll.__enter__
1610
1611[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001612
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001613static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001614select_epoll___enter___impl(pyEpoll_Object *self)
1615/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001616{
1617 if (self->epfd < 0)
1618 return pyepoll_err_closed();
1619
1620 Py_INCREF(self);
1621 return (PyObject *)self;
1622}
1623
Tal Einat6dc57e22018-06-30 23:02:48 +03001624/*[clinic input]
1625select.epoll.__exit__
1626
1627 exc_type: object = None
1628 exc_value: object = None
1629 exc_tb: object = None
1630 /
1631
1632[clinic start generated code]*/
1633
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001634static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001635select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1636 PyObject *exc_value, PyObject *exc_tb)
1637/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001638{
1639 _Py_IDENTIFIER(close);
1640
Tal Einat6dc57e22018-06-30 23:02:48 +03001641 return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001642}
1643
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001644static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 {"closed", (getter)pyepoll_get_closed, NULL,
1646 "True if the epoll handler is closed"},
1647 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001648};
1649
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001650#endif /* HAVE_EPOLL */
1651
1652#ifdef HAVE_KQUEUE
1653/* **************************************************************************
1654 * kqueue interface for BSD
1655 *
1656 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1657 * All rights reserved.
1658 *
1659 * Redistribution and use in source and binary forms, with or without
1660 * modification, are permitted provided that the following conditions
1661 * are met:
1662 * 1. Redistributions of source code must retain the above copyright
1663 * notice, this list of conditions and the following disclaimer.
1664 * 2. Redistributions in binary form must reproduce the above copyright
1665 * notice, this list of conditions and the following disclaimer in the
1666 * documentation and/or other materials provided with the distribution.
1667 *
1668 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1669 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1670 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1671 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1672 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1673 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1674 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1675 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1676 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1677 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1678 * SUCH DAMAGE.
1679 */
1680
1681#ifdef HAVE_SYS_EVENT_H
1682#include <sys/event.h>
1683#endif
1684
1685PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001686"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001687\n\
1688This object is the equivalent of the struct kevent for the C API.\n\
1689\n\
1690See the kqueue manpage for more detailed information about the meaning\n\
1691of the arguments.\n\
1692\n\
1693One minor note: while you might hope that udata could store a\n\
1694reference to a python object, it cannot, because it is impossible to\n\
1695keep a proper reference count of the object once it's passed into the\n\
1696kernel. Therefore, I have restricted it to only storing an integer. I\n\
1697recommend ignoring it and simply using the 'ident' field to key off\n\
1698of. You could also set up a dictionary on the python side to store a\n\
1699udata->object mapping.");
1700
1701typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 PyObject_HEAD
1703 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001704} kqueue_event_Object;
1705
1706static PyTypeObject kqueue_event_Type;
1707
1708#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1709
1710typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 PyObject_HEAD
1712 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001713} kqueue_queue_Object;
1714
1715static PyTypeObject kqueue_queue_Type;
1716
1717#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1718
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001719#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1720# error uintptr_t does not match void *!
1721#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1722# define T_UINTPTRT T_ULONGLONG
1723# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001724# define UINTPTRT_FMT_UNIT "K"
1725# define INTPTRT_FMT_UNIT "L"
1726#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1727# define T_UINTPTRT T_ULONG
1728# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001729# define UINTPTRT_FMT_UNIT "k"
1730# define INTPTRT_FMT_UNIT "l"
1731#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1732# define T_UINTPTRT T_UINT
1733# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001734# define UINTPTRT_FMT_UNIT "I"
1735# define INTPTRT_FMT_UNIT "i"
1736#else
1737# error uintptr_t does not match int, long, or long long!
1738#endif
1739
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001740#if SIZEOF_LONG_LONG == 8
1741# define T_INT64 T_LONGLONG
1742# define INT64_FMT_UNIT "L"
1743#elif SIZEOF_LONG == 8
1744# define T_INT64 T_LONG
1745# define INT64_FMT_UNIT "l"
1746#elif SIZEOF_INT == 8
1747# define T_INT64 T_INT
1748# define INT64_FMT_UNIT "i"
1749#else
1750# define INT64_FMT_UNIT "_"
1751#endif
1752
1753#if SIZEOF_LONG_LONG == 4
1754# define T_UINT32 T_ULONGLONG
1755# define UINT32_FMT_UNIT "K"
1756#elif SIZEOF_LONG == 4
1757# define T_UINT32 T_ULONG
1758# define UINT32_FMT_UNIT "k"
1759#elif SIZEOF_INT == 4
1760# define T_UINT32 T_UINT
1761# define UINT32_FMT_UNIT "I"
1762#else
1763# define UINT32_FMT_UNIT "_"
1764#endif
1765
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001766/*
1767 * kevent is not standard and its members vary across BSDs.
1768 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001769#ifdef __NetBSD__
1770# define FILTER_TYPE T_UINT32
1771# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1772# define FLAGS_TYPE T_UINT32
1773# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1774# define FFLAGS_TYPE T_UINT32
1775# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001776#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001777# define FILTER_TYPE T_SHORT
1778# define FILTER_FMT_UNIT "h"
1779# define FLAGS_TYPE T_USHORT
1780# define FLAGS_FMT_UNIT "H"
1781# define FFLAGS_TYPE T_UINT
1782# define FFLAGS_FMT_UNIT "I"
1783#endif
1784
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001785#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001786# define DATA_TYPE T_INT64
1787# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001788#else
1789# define DATA_TYPE T_INTPTRT
1790# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001791#endif
1792
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001793/* Unfortunately, we can't store python objects in udata, because
1794 * kevents in the kernel can be removed without warning, which would
1795 * forever lose the refcount on the object stored with it.
1796 */
1797
1798#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1799static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001800 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1801 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1802 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001804 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1806 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001807};
1808#undef KQ_OFF
1809
1810static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001811
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001812kqueue_event_repr(kqueue_event_Object *s)
1813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 char buf[1024];
1815 PyOS_snprintf(
1816 buf, sizeof(buf),
1817 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001818 "data=0x%llx udata=%p>",
1819 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1820 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001822}
1823
1824static int
1825kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 PyObject *pfd;
1828 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1829 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001830 static const char fmt[] = "O|"
1831 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1832 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1837 &pfd, &(self->e.filter), &(self->e.flags),
1838 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1839 return -1;
1840 }
1841
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001842 if (PyLong_Check(pfd)) {
1843 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 }
1845 else {
1846 self->e.ident = PyObject_AsFileDescriptor(pfd);
1847 }
1848 if (PyErr_Occurred()) {
1849 return -1;
1850 }
1851 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001852}
1853
1854static PyObject *
1855kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001858 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001861 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001863
1864#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1865 result = CMP(s->e.ident, o->e.ident)
1866 : CMP(s->e.filter, o->e.filter)
1867 : CMP(s->e.flags, o->e.flags)
1868 : CMP(s->e.fflags, o->e.fflags)
1869 : CMP(s->e.data, o->e.data)
1870 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1871 : 0;
1872#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873
stratakise8b19652017-11-02 11:32:54 +01001874 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001875}
1876
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877static PyObject *
1878kqueue_queue_err_closed(void)
1879{
Victor Stinner13423c32013-08-22 00:19:50 +02001880 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001882}
1883
1884static int
1885kqueue_queue_internal_close(kqueue_queue_Object *self)
1886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 int save_errno = 0;
1888 if (self->kqfd >= 0) {
1889 int kqfd = self->kqfd;
1890 self->kqfd = -1;
1891 Py_BEGIN_ALLOW_THREADS
1892 if (close(kqfd) < 0)
1893 save_errno = errno;
1894 Py_END_ALLOW_THREADS
1895 }
1896 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001897}
1898
1899static PyObject *
1900newKqueue_Object(PyTypeObject *type, SOCKET fd)
1901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 kqueue_queue_Object *self;
1903 assert(type != NULL && type->tp_alloc != NULL);
1904 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1905 if (self == NULL) {
1906 return NULL;
1907 }
1908
1909 if (fd == -1) {
1910 Py_BEGIN_ALLOW_THREADS
1911 self->kqfd = kqueue();
1912 Py_END_ALLOW_THREADS
1913 }
1914 else {
1915 self->kqfd = fd;
1916 }
1917 if (self->kqfd < 0) {
1918 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001919 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 return NULL;
1921 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001922
1923 if (fd == -1) {
1924 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1925 Py_DECREF(self);
1926 return NULL;
1927 }
1928 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001930}
1931
Tal Einat6dc57e22018-06-30 23:02:48 +03001932/*[clinic input]
1933@classmethod
1934select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001935
Tal Einat6dc57e22018-06-30 23:02:48 +03001936Kqueue syscall wrapper.
1937
1938For example, to start watching a socket for input:
1939>>> kq = kqueue()
1940>>> sock = socket()
1941>>> sock.connect((host, port))
1942>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1943
1944To wait one second for it to become writeable:
1945>>> kq.control(None, 1, 1000)
1946
1947To stop listening:
1948>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1949[clinic start generated code]*/
1950
1951static PyObject *
1952select_kqueue_impl(PyTypeObject *type)
1953/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001956}
1957
1958static void
1959kqueue_queue_dealloc(kqueue_queue_Object *self)
1960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 kqueue_queue_internal_close(self);
1962 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001963}
1964
Tal Einat6dc57e22018-06-30 23:02:48 +03001965/*[clinic input]
1966select.kqueue.close
1967
1968Close the kqueue control file descriptor.
1969
1970Further operations on the kqueue object will raise an exception.
1971[clinic start generated code]*/
1972
1973static PyObject *
1974select_kqueue_close_impl(kqueue_queue_Object *self)
1975/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 errno = kqueue_queue_internal_close(self);
1978 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001979 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 return NULL;
1981 }
1982 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001983}
1984
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001985static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001986kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 if (self->kqfd < 0)
1989 Py_RETURN_TRUE;
1990 else
1991 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001992}
1993
Tal Einat6dc57e22018-06-30 23:02:48 +03001994/*[clinic input]
1995select.kqueue.fileno
1996
1997Return the kqueue control file descriptor.
1998[clinic start generated code]*/
1999
2000static PyObject *
2001select_kqueue_fileno_impl(kqueue_queue_Object *self)
2002/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 if (self->kqfd < 0)
2005 return kqueue_queue_err_closed();
2006 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002007}
2008
Tal Einat6dc57e22018-06-30 23:02:48 +03002009/*[clinic input]
2010@classmethod
2011select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002012
Tal Einat6dc57e22018-06-30 23:02:48 +03002013 fd: int
2014 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002015
Tal Einat6dc57e22018-06-30 23:02:48 +03002016Create a kqueue object from a given control fd.
2017[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002018
2019static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002020select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2021/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002022{
Tal Einat6dc57e22018-06-30 23:02:48 +03002023 SOCKET s_fd = (SOCKET)fd;
2024
2025 return newKqueue_Object(type, s_fd);
2026}
2027
2028/*[clinic input]
2029select.kqueue.control
2030
2031 changelist: object
2032 Must be an iterable of kevent objects describing the changes to be made
2033 to the kernel's watch list or None.
2034 maxevents: int
2035 The maximum number of events that the kernel will return.
2036 timeout as otimeout: object = None
2037 The maximum time to wait in seconds, or else None to wait forever.
2038 This accepts floats for smaller timeouts, too.
2039 /
2040
2041Calls the kernel kevent function.
2042[clinic start generated code]*/
2043
2044static PyObject *
2045select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2046 int maxevents, PyObject *otimeout)
2047/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 int gotevents = 0;
2050 int nchanges = 0;
2051 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002052 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 PyObject *result = NULL;
2054 struct kevent *evl = NULL;
2055 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002056 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002058 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 if (self->kqfd < 0)
2061 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002062
Tal Einat6dc57e22018-06-30 23:02:48 +03002063 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 PyErr_Format(PyExc_ValueError,
2065 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002066 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 return NULL;
2068 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002069
Tal Einat6dc57e22018-06-30 23:02:48 +03002070 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 ptimeoutspec = NULL;
2072 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002073 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002074 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002075 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002076 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002077 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002078 "or None, got %.200s",
2079 Py_TYPE(otimeout)->tp_name);
2080 return NULL;
2081 }
2082
Victor Stinner4448c082015-03-31 11:48:34 +02002083 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002084 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002085
Victor Stinner4448c082015-03-31 11:48:34 +02002086 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 PyErr_SetString(PyExc_ValueError,
2088 "timeout must be positive or None");
2089 return NULL;
2090 }
Victor Stinner4448c082015-03-31 11:48:34 +02002091 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002093
Tal Einat6dc57e22018-06-30 23:02:48 +03002094 if (changelist != Py_None) {
2095 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002096 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 return NULL;
2098 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002099 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2100 PyErr_SetString(PyExc_OverflowError,
2101 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 goto error;
2103 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002104 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 chl = PyMem_New(struct kevent, nchanges);
2107 if (chl == NULL) {
2108 PyErr_NoMemory();
2109 goto error;
2110 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002111 for (i = 0; i < nchanges; ++i) {
2112 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 PyErr_SetString(PyExc_TypeError,
2115 "changelist must be an iterable of "
2116 "select.kevent objects");
2117 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002119 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002121 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002125 if (maxevents) {
2126 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (evl == NULL) {
2128 PyErr_NoMemory();
2129 goto error;
2130 }
2131 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002132
Victor Stinner4448c082015-03-31 11:48:34 +02002133 if (ptimeoutspec)
2134 deadline = _PyTime_GetMonotonicClock() + timeout;
2135
2136 do {
2137 Py_BEGIN_ALLOW_THREADS
2138 errno = 0;
2139 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002140 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002141 Py_END_ALLOW_THREADS
2142
2143 if (errno != EINTR)
2144 break;
2145
2146 /* kevent() was interrupted by a signal */
2147 if (PyErr_CheckSignals())
2148 goto error;
2149
2150 if (ptimeoutspec) {
2151 timeout = deadline - _PyTime_GetMonotonicClock();
2152 if (timeout < 0) {
2153 gotevents = 0;
2154 break;
2155 }
2156 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2157 goto error;
2158 /* retry kevent() with the recomputed timeout */
2159 }
2160 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 if (gotevents == -1) {
2163 PyErr_SetFromErrno(PyExc_OSError);
2164 goto error;
2165 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 result = PyList_New(gotevents);
2168 if (result == NULL) {
2169 goto error;
2170 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 for (i = 0; i < gotevents; i++) {
2173 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2176 if (ch == NULL) {
2177 goto error;
2178 }
2179 ch->e = evl[i];
2180 PyList_SET_ITEM(result, i, (PyObject *)ch);
2181 }
2182 PyMem_Free(chl);
2183 PyMem_Free(evl);
2184 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002185
2186 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 PyMem_Free(chl);
2188 PyMem_Free(evl);
2189 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002190 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002192}
2193
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002194static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 {"closed", (getter)kqueue_queue_get_closed, NULL,
2196 "True if the kqueue handler is closed"},
2197 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002198};
2199
Tal Einat6dc57e22018-06-30 23:02:48 +03002200#endif /* HAVE_KQUEUE */
2201
2202
2203/* ************************************************************************ */
2204
2205#include "clinic/selectmodule.c.h"
2206
2207#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2208
2209static PyMethodDef poll_methods[] = {
2210 SELECT_POLL_REGISTER_METHODDEF
2211 SELECT_POLL_MODIFY_METHODDEF
2212 SELECT_POLL_UNREGISTER_METHODDEF
2213 SELECT_POLL_POLL_METHODDEF
2214 {NULL, NULL} /* sentinel */
2215};
2216
2217static PyTypeObject poll_Type = {
2218 /* The ob_type field must be initialized in the module init function
2219 * to be portable to Windows without using C++. */
2220 PyVarObject_HEAD_INIT(NULL, 0)
2221 "select.poll", /*tp_name*/
2222 sizeof(pollObject), /*tp_basicsize*/
2223 0, /*tp_itemsize*/
2224 /* methods */
2225 (destructor)poll_dealloc, /*tp_dealloc*/
2226 0, /*tp_print*/
2227 0, /*tp_getattr*/
2228 0, /*tp_setattr*/
2229 0, /*tp_reserved*/
2230 0, /*tp_repr*/
2231 0, /*tp_as_number*/
2232 0, /*tp_as_sequence*/
2233 0, /*tp_as_mapping*/
2234 0, /*tp_hash*/
2235 0, /*tp_call*/
2236 0, /*tp_str*/
2237 0, /*tp_getattro*/
2238 0, /*tp_setattro*/
2239 0, /*tp_as_buffer*/
2240 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2241 0, /*tp_doc*/
2242 0, /*tp_traverse*/
2243 0, /*tp_clear*/
2244 0, /*tp_richcompare*/
2245 0, /*tp_weaklistoffset*/
2246 0, /*tp_iter*/
2247 0, /*tp_iternext*/
2248 poll_methods, /*tp_methods*/
2249};
2250
2251#ifdef HAVE_SYS_DEVPOLL_H
2252
2253static PyMethodDef devpoll_methods[] = {
2254 SELECT_DEVPOLL_REGISTER_METHODDEF
2255 SELECT_DEVPOLL_MODIFY_METHODDEF
2256 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2257 SELECT_DEVPOLL_POLL_METHODDEF
2258 SELECT_DEVPOLL_CLOSE_METHODDEF
2259 SELECT_DEVPOLL_FILENO_METHODDEF
2260 {NULL, NULL} /* sentinel */
2261};
2262
2263static PyTypeObject devpoll_Type = {
2264 /* The ob_type field must be initialized in the module init function
2265 * to be portable to Windows without using C++. */
2266 PyVarObject_HEAD_INIT(NULL, 0)
2267 "select.devpoll", /*tp_name*/
2268 sizeof(devpollObject), /*tp_basicsize*/
2269 0, /*tp_itemsize*/
2270 /* methods */
2271 (destructor)devpoll_dealloc, /*tp_dealloc*/
2272 0, /*tp_print*/
2273 0, /*tp_getattr*/
2274 0, /*tp_setattr*/
2275 0, /*tp_reserved*/
2276 0, /*tp_repr*/
2277 0, /*tp_as_number*/
2278 0, /*tp_as_sequence*/
2279 0, /*tp_as_mapping*/
2280 0, /*tp_hash*/
2281 0, /*tp_call*/
2282 0, /*tp_str*/
2283 0, /*tp_getattro*/
2284 0, /*tp_setattro*/
2285 0, /*tp_as_buffer*/
2286 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2287 0, /*tp_doc*/
2288 0, /*tp_traverse*/
2289 0, /*tp_clear*/
2290 0, /*tp_richcompare*/
2291 0, /*tp_weaklistoffset*/
2292 0, /*tp_iter*/
2293 0, /*tp_iternext*/
2294 devpoll_methods, /*tp_methods*/
2295 0, /* tp_members */
2296 devpoll_getsetlist, /* tp_getset */
2297};
2298
2299#endif /* HAVE_SYS_DEVPOLL_H */
2300
2301#endif /* HAVE_POLL */
2302
2303#ifdef HAVE_EPOLL
2304
2305static PyMethodDef pyepoll_methods[] = {
2306 SELECT_EPOLL_FROMFD_METHODDEF
2307 SELECT_EPOLL_CLOSE_METHODDEF
2308 SELECT_EPOLL_FILENO_METHODDEF
2309 SELECT_EPOLL_MODIFY_METHODDEF
2310 SELECT_EPOLL_REGISTER_METHODDEF
2311 SELECT_EPOLL_UNREGISTER_METHODDEF
2312 SELECT_EPOLL_POLL_METHODDEF
2313 SELECT_EPOLL___ENTER___METHODDEF
2314 SELECT_EPOLL___EXIT___METHODDEF
2315 {NULL, NULL},
2316};
2317
2318static PyTypeObject pyEpoll_Type = {
2319 PyVarObject_HEAD_INIT(NULL, 0)
2320 "select.epoll", /* tp_name */
2321 sizeof(pyEpoll_Object), /* tp_basicsize */
2322 0, /* tp_itemsize */
2323 (destructor)pyepoll_dealloc, /* tp_dealloc */
2324 0, /* tp_print */
2325 0, /* tp_getattr */
2326 0, /* tp_setattr */
2327 0, /* tp_reserved */
2328 0, /* tp_repr */
2329 0, /* tp_as_number */
2330 0, /* tp_as_sequence */
2331 0, /* tp_as_mapping */
2332 0, /* tp_hash */
2333 0, /* tp_call */
2334 0, /* tp_str */
2335 PyObject_GenericGetAttr, /* tp_getattro */
2336 0, /* tp_setattro */
2337 0, /* tp_as_buffer */
2338 Py_TPFLAGS_DEFAULT, /* tp_flags */
2339 select_epoll__doc__, /* tp_doc */
2340 0, /* tp_traverse */
2341 0, /* tp_clear */
2342 0, /* tp_richcompare */
2343 0, /* tp_weaklistoffset */
2344 0, /* tp_iter */
2345 0, /* tp_iternext */
2346 pyepoll_methods, /* tp_methods */
2347 0, /* tp_members */
2348 pyepoll_getsetlist, /* tp_getset */
2349 0, /* tp_base */
2350 0, /* tp_dict */
2351 0, /* tp_descr_get */
2352 0, /* tp_descr_set */
2353 0, /* tp_dictoffset */
2354 0, /* tp_init */
2355 0, /* tp_alloc */
2356 select_epoll, /* tp_new */
2357 0, /* tp_free */
2358};
2359
2360#endif /* HAVE_EPOLL */
2361
2362#ifdef HAVE_KQUEUE
2363
2364static PyTypeObject kqueue_event_Type = {
2365 PyVarObject_HEAD_INIT(NULL, 0)
2366 "select.kevent", /* tp_name */
2367 sizeof(kqueue_event_Object), /* tp_basicsize */
2368 0, /* tp_itemsize */
2369 0, /* tp_dealloc */
2370 0, /* tp_print */
2371 0, /* tp_getattr */
2372 0, /* tp_setattr */
2373 0, /* tp_reserved */
2374 (reprfunc)kqueue_event_repr, /* tp_repr */
2375 0, /* tp_as_number */
2376 0, /* tp_as_sequence */
2377 0, /* tp_as_mapping */
2378 0, /* tp_hash */
2379 0, /* tp_call */
2380 0, /* tp_str */
2381 0, /* tp_getattro */
2382 0, /* tp_setattro */
2383 0, /* tp_as_buffer */
2384 Py_TPFLAGS_DEFAULT, /* tp_flags */
2385 kqueue_event_doc, /* tp_doc */
2386 0, /* tp_traverse */
2387 0, /* tp_clear */
2388 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
2389 0, /* tp_weaklistoffset */
2390 0, /* tp_iter */
2391 0, /* tp_iternext */
2392 0, /* tp_methods */
2393 kqueue_event_members, /* tp_members */
2394 0, /* tp_getset */
2395 0, /* tp_base */
2396 0, /* tp_dict */
2397 0, /* tp_descr_get */
2398 0, /* tp_descr_set */
2399 0, /* tp_dictoffset */
2400 (initproc)kqueue_event_init, /* tp_init */
2401 0, /* tp_alloc */
2402 0, /* tp_new */
2403 0, /* tp_free */
2404};
2405
2406static PyMethodDef kqueue_queue_methods[] = {
2407 SELECT_KQUEUE_FROMFD_METHODDEF
2408 SELECT_KQUEUE_CLOSE_METHODDEF
2409 SELECT_KQUEUE_FILENO_METHODDEF
2410 SELECT_KQUEUE_CONTROL_METHODDEF
2411 {NULL, NULL},
2412};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002413
2414static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 PyVarObject_HEAD_INIT(NULL, 0)
2416 "select.kqueue", /* tp_name */
2417 sizeof(kqueue_queue_Object), /* tp_basicsize */
2418 0, /* tp_itemsize */
2419 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2420 0, /* tp_print */
2421 0, /* tp_getattr */
2422 0, /* tp_setattr */
2423 0, /* tp_reserved */
2424 0, /* tp_repr */
2425 0, /* tp_as_number */
2426 0, /* tp_as_sequence */
2427 0, /* tp_as_mapping */
2428 0, /* tp_hash */
2429 0, /* tp_call */
2430 0, /* tp_str */
2431 0, /* tp_getattro */
2432 0, /* tp_setattro */
2433 0, /* tp_as_buffer */
2434 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tal Einat6dc57e22018-06-30 23:02:48 +03002435 select_kqueue__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 0, /* tp_traverse */
2437 0, /* tp_clear */
2438 0, /* tp_richcompare */
2439 0, /* tp_weaklistoffset */
2440 0, /* tp_iter */
2441 0, /* tp_iternext */
2442 kqueue_queue_methods, /* tp_methods */
2443 0, /* tp_members */
2444 kqueue_queue_getsetlist, /* tp_getset */
2445 0, /* tp_base */
2446 0, /* tp_dict */
2447 0, /* tp_descr_get */
2448 0, /* tp_descr_set */
2449 0, /* tp_dictoffset */
2450 0, /* tp_init */
2451 0, /* tp_alloc */
Tal Einat6dc57e22018-06-30 23:02:48 +03002452 select_kqueue, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002454};
2455
2456#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002457
2458
2459
2460
2461
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002462/* ************************************************************************ */
2463
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002464
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002465static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002466 SELECT_SELECT_METHODDEF
2467 SELECT_POLL_METHODDEF
2468 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002470};
2471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002472PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002473"This module supports asynchronous I/O on multiple file descriptors.\n\
2474\n\
2475*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002476On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002477
Martin v. Löwis1a214512008-06-11 05:26:20 +00002478
2479static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 PyModuleDef_HEAD_INIT,
2481 "select",
2482 module_doc,
2483 -1,
2484 select_methods,
2485 NULL,
2486 NULL,
2487 NULL,
2488 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002489};
2490
Jesus Cead8b9ae62011-11-14 19:07:41 +01002491
2492
2493
Mark Hammond62b1ab12002-07-23 06:31:15 +00002494PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002495PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002497 PyObject *m;
2498 m = PyModule_Create(&selectmodule);
2499 if (m == NULL)
2500 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002501
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002502 Py_INCREF(PyExc_OSError);
2503 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002504
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002505#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002506#ifdef HAVE_BROKEN_PIPE_BUF
2507#undef PIPE_BUF
2508#define PIPE_BUF 512
2509#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002510 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002511#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002512
Charles-François Natali986a56c2013-01-19 12:19:10 +01002513#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002514#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 if (select_have_broken_poll()) {
2516 if (PyObject_DelAttrString(m, "poll") == -1) {
2517 PyErr_Clear();
2518 }
2519 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002520#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002522#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 if (PyType_Ready(&poll_Type) < 0)
2524 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002525 PyModule_AddIntMacro(m, POLLIN);
2526 PyModule_AddIntMacro(m, POLLPRI);
2527 PyModule_AddIntMacro(m, POLLOUT);
2528 PyModule_AddIntMacro(m, POLLERR);
2529 PyModule_AddIntMacro(m, POLLHUP);
2530 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002531
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002532#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002533 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002534#endif
2535#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002536 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002537#endif
2538#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002539 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002540#endif
2541#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002542 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002543#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002544#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002545 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002546#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002547#ifdef POLLRDHUP
2548 /* Kernel 2.6.17+ */
2549 PyModule_AddIntMacro(m, POLLRDHUP);
2550#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002552#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002553
Jesus Cead8b9ae62011-11-14 19:07:41 +01002554#ifdef HAVE_SYS_DEVPOLL_H
2555 if (PyType_Ready(&devpoll_Type) < 0)
2556 return NULL;
2557#endif
2558
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002559#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2561 if (PyType_Ready(&pyEpoll_Type) < 0)
2562 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 Py_INCREF(&pyEpoll_Type);
2565 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002566
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002567 PyModule_AddIntMacro(m, EPOLLIN);
2568 PyModule_AddIntMacro(m, EPOLLOUT);
2569 PyModule_AddIntMacro(m, EPOLLPRI);
2570 PyModule_AddIntMacro(m, EPOLLERR);
2571 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002572#ifdef EPOLLRDHUP
2573 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002574 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002575#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002576 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002577#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002579 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002580#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002581#ifdef EPOLLEXCLUSIVE
2582 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2583#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002584
2585#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002586 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002587#endif
2588#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002589 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002590#endif
2591#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002592 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002593#endif
2594#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002595 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002596#endif
2597#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002598 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002599#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002600
Benjamin Peterson95c16622011-12-27 15:36:32 -06002601#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002602 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002603#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002604#endif /* HAVE_EPOLL */
2605
2606#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 kqueue_event_Type.tp_new = PyType_GenericNew;
2608 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2609 if(PyType_Ready(&kqueue_event_Type) < 0)
2610 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612 Py_INCREF(&kqueue_event_Type);
2613 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2616 if(PyType_Ready(&kqueue_queue_Type) < 0)
2617 return NULL;
2618 Py_INCREF(&kqueue_queue_Type);
2619 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2620
2621 /* event filters */
2622 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2623 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002624#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002626#endif
2627#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002629#endif
2630#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002632#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002633#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002635#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002636#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002638#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 /* event flags */
2642 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2643 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2644 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2645 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2646 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2647 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002648
Berker Peksag7ec64562016-09-14 18:16:59 +03002649#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002651#endif
2652#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002654#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2657 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002660#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002662#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002664 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002665#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002666 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2667 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2668 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2669 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2670 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2671 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2672 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002673#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002676#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002677 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2678 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2679 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2680 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2681 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002683 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2684 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2685 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002686#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687
2688 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002689#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002690 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2691 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2692 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002693#endif
2694
2695#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002697}