blob: 9ad6f8bdb7aee42b2c353a9faaf92614073a64c6 [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) {
338 n = 0;
339 break;
340 }
341 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200342 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200343 }
344 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000345
Thomas Heller106f4c72002-09-24 16:51:00 +0000346#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200348 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000350#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200352 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000354#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 else {
356 /* any of these three calls can raise an exception. it's more
357 convenient to test for this after all three calls... but
358 is that acceptable?
359 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300360 rlist = set2list(&ifdset, rfd2obj);
361 wlist = set2list(&ofdset, wfd2obj);
362 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (PyErr_Occurred())
364 ret = NULL;
365 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300366 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000367
Tal Einat6dc57e22018-06-30 23:02:48 +0300368 Py_XDECREF(rlist);
369 Py_XDECREF(wlist);
370 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 }
372
Barry Warsawc1cb3601996-12-12 22:16:21 +0000373 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 reap_obj(rfd2obj);
375 reap_obj(wfd2obj);
376 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000377#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 PyMem_DEL(rfd2obj);
379 PyMem_DEL(wfd2obj);
380 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000381#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000383}
384
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000385#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000387 * poll() support
388 */
389
390typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 PyObject_HEAD
392 PyObject *dict;
393 int ufd_uptodate;
394 int ufd_len;
395 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300396 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000397} pollObject;
398
Jeremy Hylton938ace62002-07-17 16:30:39 +0000399static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000402 contained within a pollObject. Return 1 on success, 0 on an error.
403*/
404
405static int
406update_ufd_array(pollObject *self)
407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 Py_ssize_t i, pos;
409 PyObject *key, *value;
410 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000411
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200412 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
414 if (self->ufds == NULL) {
415 self->ufds = old_ufds;
416 PyErr_NoMemory();
417 return 0;
418 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 i = pos = 0;
421 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200422 assert(i < self->ufd_len);
423 /* Never overflow */
424 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200425 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 i++;
427 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200428 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 self->ufd_uptodate = 1;
430 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000431}
432
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200433static int
434ushort_converter(PyObject *obj, void *ptr)
435{
436 unsigned long uval;
437
438 uval = PyLong_AsUnsignedLong(obj);
439 if (uval == (unsigned long)-1 && PyErr_Occurred())
440 return 0;
441 if (uval > USHRT_MAX) {
442 PyErr_SetString(PyExc_OverflowError,
443 "Python int too large for C unsigned short");
444 return 0;
445 }
446
447 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
448 return 1;
449}
450
Tal Einat6dc57e22018-06-30 23:02:48 +0300451/*[clinic input]
452select.poll.register
453
454 fd: fildes
455 either an integer, or an object with a fileno() method returning an int
456 eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
457 an optional bitmask describing the type of events to check for
458 /
459
460Register a file descriptor with the polling object.
461[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000462
463static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300464select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
465/*[clinic end generated code: output=0dc7173c800a4a65 input=499d96a2836217f5]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000466{
Tal Einat6dc57e22018-06-30 23:02:48 +0300467 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 /* Add entry to the internal dictionary: the key is the
471 file descriptor, and the value is the event mask. */
472 key = PyLong_FromLong(fd);
473 if (key == NULL)
474 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300475 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 if (value == NULL) {
477 Py_DECREF(key);
478 return NULL;
479 }
480 err = PyDict_SetItem(self->dict, key, value);
481 Py_DECREF(key);
482 Py_DECREF(value);
483 if (err < 0)
484 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 self->ufd_uptodate = 0;
487
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200488 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000489}
490
Tal Einat6dc57e22018-06-30 23:02:48 +0300491
492/*[clinic input]
493select.poll.modify
494
495 fd: fildes
496 either an integer, or an object with a fileno() method returning
497 an int
498 eventmask: object(converter="ushort_converter", type="unsigned short")
499 a bitmask describing the type of events to check for
500 /
501
502Modify an already registered file descriptor.
503[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000504
505static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300506select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
507/*[clinic end generated code: output=1a7b88bf079eff17 input=b8e0e04a1264b78f]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000508{
Tal Einat6dc57e22018-06-30 23:02:48 +0300509 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 /* Modify registered fd */
513 key = PyLong_FromLong(fd);
514 if (key == NULL)
515 return NULL;
516 if (PyDict_GetItem(self->dict, key) == NULL) {
517 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200518 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200519 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 return NULL;
521 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300522 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 if (value == NULL) {
524 Py_DECREF(key);
525 return NULL;
526 }
527 err = PyDict_SetItem(self->dict, key, value);
528 Py_DECREF(key);
529 Py_DECREF(value);
530 if (err < 0)
531 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 self->ufd_uptodate = 0;
534
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200535 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000536}
537
538
Tal Einat6dc57e22018-06-30 23:02:48 +0300539/*[clinic input]
540select.poll.unregister
541
542 fd: fildes
543 /
544
545Remove a file descriptor being tracked by the polling object.
546[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000547
548static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300549select_poll_unregister_impl(pollObject *self, int fd)
550/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 /* Check whether the fd is already in the array */
555 key = PyLong_FromLong(fd);
556 if (key == NULL)
557 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 if (PyDict_DelItem(self->dict, key) == -1) {
560 Py_DECREF(key);
561 /* This will simply raise the KeyError set by PyDict_DelItem
562 if the file descriptor isn't registered. */
563 return NULL;
564 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 Py_DECREF(key);
567 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000568
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200569 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000570}
571
Tal Einat6dc57e22018-06-30 23:02:48 +0300572/*[clinic input]
573select.poll.poll
574
575 timeout as timeout_obj: object = None
576 /
577
578Polls the set of registered file descriptors.
579
580Returns a list containing any descriptors that have events or errors to
581report, as a list of (fd, event) 2-tuples.
582[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583
584static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300585select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
586/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000587{
Tal Einat6dc57e22018-06-30 23:02:48 +0300588 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200589 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200591 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200592 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000593
Tal Einat6dc57e22018-06-30 23:02:48 +0300594 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200595 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100596 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200597 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
598 PyErr_SetString(PyExc_TypeError,
599 "timeout must be an integer or None");
600 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200602 }
603
Pablo Galindo2c15b292017-10-17 15:14:41 +0100604 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200605 if (ms < INT_MIN || ms > INT_MAX) {
606 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200608 }
609
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200610 if (timeout >= 0) {
611 deadline = _PyTime_GetMonotonicClock() + timeout;
612 }
613 }
614
615 /* On some OSes, typically BSD-based ones, the timeout parameter of the
616 poll() syscall, when negative, must be exactly INFTIM, where defined,
617 or -1. See issue 31334. */
618 if (ms < 0) {
619#ifdef INFTIM
620 ms = INFTIM;
621#else
622 ms = -1;
623#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000625
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300626 /* Avoid concurrent poll() invocation, issue 8865 */
627 if (self->poll_running) {
628 PyErr_SetString(PyExc_RuntimeError,
629 "concurrent poll() invocation");
630 return NULL;
631 }
632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 /* Ensure the ufd array is up to date */
634 if (!self->ufd_uptodate)
635 if (update_ufd_array(self) == 0)
636 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000637
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300638 self->poll_running = 1;
639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200641 async_err = 0;
642 do {
643 Py_BEGIN_ALLOW_THREADS
644 errno = 0;
645 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
646 Py_END_ALLOW_THREADS
647
648 if (errno != EINTR)
649 break;
650
651 /* poll() was interrupted by a signal */
652 if (PyErr_CheckSignals()) {
653 async_err = 1;
654 break;
655 }
656
657 if (timeout >= 0) {
658 timeout = deadline - _PyTime_GetMonotonicClock();
659 if (timeout < 0) {
660 poll_result = 0;
661 break;
662 }
663 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
664 /* retry poll() with the recomputed timeout */
665 }
666 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000667
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300668 self->poll_running = 0;
669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200671 if (!async_err)
672 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 return NULL;
674 }
675
676 /* build the result list */
677
678 result_list = PyList_New(poll_result);
679 if (!result_list)
680 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200682 for (i = 0, j = 0; j < poll_result; j++) {
683 /* skip to the next fired descriptor */
684 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 i++;
686 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200687 /* if we hit a NULL return, set value to NULL
688 and break out of loop; code at end will
689 clean up result_list */
690 value = PyTuple_New(2);
691 if (value == NULL)
692 goto error;
693 num = PyLong_FromLong(self->ufds[i].fd);
694 if (num == NULL) {
695 Py_DECREF(value);
696 goto error;
697 }
698 PyTuple_SET_ITEM(value, 0, num);
699
700 /* The &0xffff is a workaround for AIX. 'revents'
701 is a 16-bit short, and IBM assigned POLLNVAL
702 to be 0x8000, so the conversion to int results
703 in a negative number. See SF bug #923315. */
704 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
705 if (num == NULL) {
706 Py_DECREF(value);
707 goto error;
708 }
709 PyTuple_SET_ITEM(value, 1, num);
710 if ((PyList_SetItem(result_list, j, value)) == -1) {
711 Py_DECREF(value);
712 goto error;
713 }
714 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 }
716 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000717
718 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 Py_DECREF(result_list);
720 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000721}
722
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000723static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000724newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 pollObject *self;
727 self = PyObject_New(pollObject, &poll_Type);
728 if (self == NULL)
729 return NULL;
730 /* ufd_uptodate is a Boolean, denoting whether the
731 array pointed to by ufds matches the contents of the dictionary. */
732 self->ufd_uptodate = 0;
733 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300734 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 self->dict = PyDict_New();
736 if (self->dict == NULL) {
737 Py_DECREF(self);
738 return NULL;
739 }
740 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000741}
742
743static void
744poll_dealloc(pollObject *self)
745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 if (self->ufds != NULL)
747 PyMem_DEL(self->ufds);
748 Py_XDECREF(self->dict);
749 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000750}
751
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000752
Jesus Cead8b9ae62011-11-14 19:07:41 +0100753#ifdef HAVE_SYS_DEVPOLL_H
754typedef struct {
755 PyObject_HEAD
756 int fd_devpoll;
757 int max_n_fds;
758 int n_fds;
759 struct pollfd *fds;
760} devpollObject;
761
762static PyTypeObject devpoll_Type;
763
Victor Stinner13423c32013-08-22 00:19:50 +0200764static PyObject *
765devpoll_err_closed(void)
766{
767 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
768 return NULL;
769}
770
Jesus Cead8b9ae62011-11-14 19:07:41 +0100771static int devpoll_flush(devpollObject *self)
772{
773 int size, n;
774
775 if (!self->n_fds) return 0;
776
777 size = sizeof(struct pollfd)*self->n_fds;
778 self->n_fds = 0;
779
Victor Stinner54799672015-03-19 23:33:09 +0100780 n = _Py_write(self->fd_devpoll, self->fds, size);
781 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100782 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100783
Jesus Cead8b9ae62011-11-14 19:07:41 +0100784 if (n < size) {
785 /*
786 ** Data writed to /dev/poll is a binary data structure. It is not
787 ** clear what to do if a partial write occurred. For now, raise
788 ** an exception and see if we actually found this problem in
789 ** the wild.
790 ** See http://bugs.python.org/issue6397.
791 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300792 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100793 "Please, report at http://bugs.python.org/. "
794 "Data to report: Size tried: %d, actual size written: %d.",
795 size, n);
796 return -1;
797 }
798 return 0;
799}
800
801static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300802internal_devpoll_register(devpollObject *self, int fd,
803 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100804{
Victor Stinner13423c32013-08-22 00:19:50 +0200805 if (self->fd_devpoll < 0)
806 return devpoll_err_closed();
807
Jesus Cead8b9ae62011-11-14 19:07:41 +0100808 if (remove) {
809 self->fds[self->n_fds].fd = fd;
810 self->fds[self->n_fds].events = POLLREMOVE;
811
812 if (++self->n_fds == self->max_n_fds) {
813 if (devpoll_flush(self))
814 return NULL;
815 }
816 }
817
818 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200819 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100820
821 if (++self->n_fds == self->max_n_fds) {
822 if (devpoll_flush(self))
823 return NULL;
824 }
825
826 Py_RETURN_NONE;
827}
828
Tal Einat6dc57e22018-06-30 23:02:48 +0300829/*[clinic input]
830select.devpoll.register
831
832 fd: fildes
833 either an integer, or an object with a fileno() method returning
834 an int
835 eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
836 an optional bitmask describing the type of events to check for
837 /
838
839Register a file descriptor with the polling object.
840[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100841
842static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300843select_devpoll_register_impl(devpollObject *self, int fd,
844 unsigned short eventmask)
845/*[clinic end generated code: output=6e07fe8b74abba0c input=389a0785bb8feb57]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100846{
Tal Einat6dc57e22018-06-30 23:02:48 +0300847 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100848}
849
Tal Einat6dc57e22018-06-30 23:02:48 +0300850/*[clinic input]
851select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100852
Tal Einat6dc57e22018-06-30 23:02:48 +0300853 fd: fildes
854 either an integer, or an object with a fileno() method returning
855 an int
856 eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
857 an optional bitmask describing the type of events to check for
858 /
859
860Modify a possible already registered file descriptor.
861[clinic start generated code]*/
862
863static PyObject *
864select_devpoll_modify_impl(devpollObject *self, int fd,
865 unsigned short eventmask)
866/*[clinic end generated code: output=bc2e6d23aaff98b4 input=f0d7de3889cc55fb]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100867static PyObject *
868devpoll_modify(devpollObject *self, PyObject *args)
869{
Tal Einat6dc57e22018-06-30 23:02:48 +0300870 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100871}
872
Tal Einat6dc57e22018-06-30 23:02:48 +0300873/*[clinic input]
874select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100875
Tal Einat6dc57e22018-06-30 23:02:48 +0300876 fd: fildes
877 /
878
879Remove a file descriptor being tracked by the polling object.
880[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100881
882static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300883select_devpoll_unregister_impl(devpollObject *self, int fd)
884/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100885{
Victor Stinner13423c32013-08-22 00:19:50 +0200886 if (self->fd_devpoll < 0)
887 return devpoll_err_closed();
888
Jesus Cead8b9ae62011-11-14 19:07:41 +0100889 self->fds[self->n_fds].fd = fd;
890 self->fds[self->n_fds].events = POLLREMOVE;
891
892 if (++self->n_fds == self->max_n_fds) {
893 if (devpoll_flush(self))
894 return NULL;
895 }
896
897 Py_RETURN_NONE;
898}
899
Tal Einat6dc57e22018-06-30 23:02:48 +0300900/*[clinic input]
901select.devpoll.poll
902 timeout as timeout_obj: object = None
903 /
904
905Polls the set of registered file descriptors.
906
907Returns a list containing any descriptors that have events or errors to
908report, as a list of (fd, event) 2-tuples.
909[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100910
911static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300912select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
913/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100914{
915 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200916 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100917 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100918 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200919 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920
Victor Stinner13423c32013-08-22 00:19:50 +0200921 if (self->fd_devpoll < 0)
922 return devpoll_err_closed();
923
Jesus Cead8b9ae62011-11-14 19:07:41 +0100924 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300925 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100926 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200927 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928 }
929 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200930 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100931 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
933 PyErr_SetString(PyExc_TypeError,
934 "timeout must be an integer or None");
935 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100936 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200937 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100938
Pablo Galindo2c15b292017-10-17 15:14:41 +0100939 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200940 if (ms < -1 || ms > INT_MAX) {
941 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
942 return NULL;
943 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100944 }
945
946 if (devpoll_flush(self))
947 return NULL;
948
949 dvp.dp_fds = self->fds;
950 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200951 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100952
Victor Stinner45ca48b2015-03-31 12:10:33 +0200953 if (timeout >= 0)
954 deadline = _PyTime_GetMonotonicClock() + timeout;
955
956 do {
957 /* call devpoll() */
958 Py_BEGIN_ALLOW_THREADS
959 errno = 0;
960 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
961 Py_END_ALLOW_THREADS
962
963 if (errno != EINTR)
964 break;
965
966 /* devpoll() was interrupted by a signal */
967 if (PyErr_CheckSignals())
968 return NULL;
969
970 if (timeout >= 0) {
971 timeout = deadline - _PyTime_GetMonotonicClock();
972 if (timeout < 0) {
973 poll_result = 0;
974 break;
975 }
976 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
977 dvp.dp_timeout = (int)ms;
978 /* retry devpoll() with the recomputed timeout */
979 }
980 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100981
982 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300983 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100984 return NULL;
985 }
986
987 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100988 result_list = PyList_New(poll_result);
989 if (!result_list)
990 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200991
992 for (i = 0; i < poll_result; i++) {
993 num1 = PyLong_FromLong(self->fds[i].fd);
994 num2 = PyLong_FromLong(self->fds[i].revents);
995 if ((num1 == NULL) || (num2 == NULL)) {
996 Py_XDECREF(num1);
997 Py_XDECREF(num2);
998 goto error;
999 }
1000 value = PyTuple_Pack(2, num1, num2);
1001 Py_DECREF(num1);
1002 Py_DECREF(num2);
1003 if (value == NULL)
1004 goto error;
1005 if ((PyList_SetItem(result_list, i, value)) == -1) {
1006 Py_DECREF(value);
1007 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001008 }
1009 }
1010
1011 return result_list;
1012
1013 error:
1014 Py_DECREF(result_list);
1015 return NULL;
1016}
1017
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001018static int
1019devpoll_internal_close(devpollObject *self)
1020{
1021 int save_errno = 0;
1022 if (self->fd_devpoll >= 0) {
1023 int fd = self->fd_devpoll;
1024 self->fd_devpoll = -1;
1025 Py_BEGIN_ALLOW_THREADS
1026 if (close(fd) < 0)
1027 save_errno = errno;
1028 Py_END_ALLOW_THREADS
1029 }
1030 return save_errno;
1031}
1032
Tal Einat6dc57e22018-06-30 23:02:48 +03001033/*[clinic input]
1034select.devpoll.close
1035
1036Close the devpoll file descriptor.
1037
1038Further operations on the devpoll object will raise an exception.
1039[clinic start generated code]*/
1040
1041static PyObject *
1042select_devpoll_close_impl(devpollObject *self)
1043/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001044{
1045 errno = devpoll_internal_close(self);
1046 if (errno < 0) {
1047 PyErr_SetFromErrno(PyExc_OSError);
1048 return NULL;
1049 }
1050 Py_RETURN_NONE;
1051}
1052
Victor Stinner13423c32013-08-22 00:19:50 +02001053static PyObject*
1054devpoll_get_closed(devpollObject *self)
1055{
1056 if (self->fd_devpoll < 0)
1057 Py_RETURN_TRUE;
1058 else
1059 Py_RETURN_FALSE;
1060}
1061
Tal Einat6dc57e22018-06-30 23:02:48 +03001062/*[clinic input]
1063select.devpoll.fileno
1064
1065Return the file descriptor.
1066[clinic start generated code]*/
1067
1068static PyObject *
1069select_devpoll_fileno_impl(devpollObject *self)
1070/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001071{
1072 if (self->fd_devpoll < 0)
1073 return devpoll_err_closed();
1074 return PyLong_FromLong(self->fd_devpoll);
1075}
1076
Victor Stinner13423c32013-08-22 00:19:50 +02001077static PyGetSetDef devpoll_getsetlist[] = {
1078 {"closed", (getter)devpoll_get_closed, NULL,
1079 "True if the devpoll object is closed"},
1080 {0},
1081};
1082
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083static devpollObject *
1084newDevPollObject(void)
1085{
1086 devpollObject *self;
1087 int fd_devpoll, limit_result;
1088 struct pollfd *fds;
1089 struct rlimit limit;
1090
Jesus Cead8b9ae62011-11-14 19:07:41 +01001091 /*
1092 ** If we try to process more that getrlimit()
1093 ** fds, the kernel will give an error, so
1094 ** we set the limit here. It is a dynamic
1095 ** value, because we can change rlimit() anytime.
1096 */
1097 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001098 if (limit_result == -1) {
1099 PyErr_SetFromErrno(PyExc_OSError);
1100 return NULL;
1101 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001102
1103 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1104 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001105 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001106
1107 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1108 if (fds == NULL) {
1109 close(fd_devpoll);
1110 PyErr_NoMemory();
1111 return NULL;
1112 }
1113
1114 self = PyObject_New(devpollObject, &devpoll_Type);
1115 if (self == NULL) {
1116 close(fd_devpoll);
1117 PyMem_DEL(fds);
1118 return NULL;
1119 }
1120 self->fd_devpoll = fd_devpoll;
1121 self->max_n_fds = limit.rlim_cur;
1122 self->n_fds = 0;
1123 self->fds = fds;
1124
1125 return self;
1126}
1127
1128static void
1129devpoll_dealloc(devpollObject *self)
1130{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001131 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001132 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001133 PyObject_Del(self);
1134}
1135
Jesus Cead8b9ae62011-11-14 19:07:41 +01001136#endif /* HAVE_SYS_DEVPOLL_H */
1137
1138
Tal Einat6dc57e22018-06-30 23:02:48 +03001139/*[clinic input]
1140select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001141
Tal Einat6dc57e22018-06-30 23:02:48 +03001142Returns a polling object.
1143
1144This object supports registering and unregistering file descriptors, and then
1145polling them for I/O events.
1146[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001147
1148static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001149select_poll_impl(PyObject *module)
1150/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001153}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001154
Jesus Cead8b9ae62011-11-14 19:07:41 +01001155#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001156
1157/*[clinic input]
1158select.devpoll
1159
1160Returns a polling object.
1161
1162This object supports registering and unregistering file descriptors, and then
1163polling them for I/O events.
1164[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001165
1166static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001167select_devpoll_impl(PyObject *module)
1168/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001169{
1170 return (PyObject *)newDevPollObject();
1171}
1172#endif
1173
1174
Thomas Wouters477c8d52006-05-27 19:21:47 +00001175#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001177 * On some systems poll() sets errno on invalid file descriptors. We test
1178 * for this at runtime because this bug may be fixed or introduced between
1179 * OS releases.
1180 */
1181static int select_have_broken_poll(void)
1182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 int poll_test;
1184 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 /* Create a file descriptor to make invalid */
1189 if (pipe(filedes) < 0) {
1190 return 1;
1191 }
1192 poll_struct.fd = filedes[0];
1193 close(filedes[0]);
1194 close(filedes[1]);
1195 poll_test = poll(&poll_struct, 1, 0);
1196 if (poll_test < 0) {
1197 return 1;
1198 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1199 return 1;
1200 }
1201 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001202}
1203#endif /* __APPLE__ */
1204
1205#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001206
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001207#ifdef HAVE_EPOLL
1208/* **************************************************************************
1209 * epoll interface for Linux 2.6
1210 *
1211 * Written by Christian Heimes
1212 * Inspired by Twisted's _epoll.pyx and select.poll()
1213 */
1214
1215#ifdef HAVE_SYS_EPOLL_H
1216#include <sys/epoll.h>
1217#endif
1218
1219typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001221 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001222} pyEpoll_Object;
1223
1224static PyTypeObject pyEpoll_Type;
1225#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1226
1227static PyObject *
1228pyepoll_err_closed(void)
1229{
Victor Stinner13423c32013-08-22 00:19:50 +02001230 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001232}
1233
1234static int
1235pyepoll_internal_close(pyEpoll_Object *self)
1236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 int save_errno = 0;
1238 if (self->epfd >= 0) {
1239 int epfd = self->epfd;
1240 self->epfd = -1;
1241 Py_BEGIN_ALLOW_THREADS
1242 if (close(epfd) < 0)
1243 save_errno = errno;
1244 Py_END_ALLOW_THREADS
1245 }
1246 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001247}
1248
1249static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001250newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 assert(type != NULL && type->tp_alloc != NULL);
1255 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1256 if (self == NULL)
1257 return NULL;
1258
1259 if (fd == -1) {
1260 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001261#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001262 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1263#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001264 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001265#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 Py_END_ALLOW_THREADS
1267 }
1268 else {
1269 self->epfd = fd;
1270 }
1271 if (self->epfd < 0) {
1272 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001273 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 return NULL;
1275 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001276
1277#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001278 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001279 Py_DECREF(self);
1280 return NULL;
1281 }
1282#endif
1283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001285}
1286
1287
Tal Einat6dc57e22018-06-30 23:02:48 +03001288/*[clinic input]
1289@classmethod
1290select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001291
Tal Einat6dc57e22018-06-30 23:02:48 +03001292 sizehint: int = -1
1293 The expected number of events to be registered. It must be positive,
1294 or -1 to use the default. It is only used on older systems where
1295 epoll_create1() is not available; otherwise it has no effect (though its
1296 value is still checked).
1297 flags: int = 0
1298 Deprecated and completely ignored. However, when supplied, its value
1299 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1300
1301Returns an epolling object.
1302[clinic start generated code]*/
1303
1304static PyObject *
1305select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1306/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1307{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001308 if (sizehint == -1) {
1309 sizehint = FD_SETSIZE - 1;
1310 }
1311 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001312 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001313 return NULL;
1314 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001315
1316#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001317 if (flags && flags != EPOLL_CLOEXEC) {
1318 PyErr_SetString(PyExc_OSError, "invalid flags");
1319 return NULL;
1320 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001321#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001322
Berker Peksage2197d12016-09-26 23:30:41 +03001323 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001324}
1325
1326
1327static void
1328pyepoll_dealloc(pyEpoll_Object *self)
1329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 (void)pyepoll_internal_close(self);
1331 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332}
1333
Tal Einat6dc57e22018-06-30 23:02:48 +03001334/*[clinic input]
1335select.epoll.close
1336
1337Close the epoll control file descriptor.
1338
1339Further operations on the epoll object will raise an exception.
1340[clinic start generated code]*/
1341
1342static PyObject *
1343select_epoll_close_impl(pyEpoll_Object *self)
1344/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 errno = pyepoll_internal_close(self);
1347 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001348 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 return NULL;
1350 }
1351 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001352}
1353
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001354
1355static PyObject*
1356pyepoll_get_closed(pyEpoll_Object *self)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 if (self->epfd < 0)
1359 Py_RETURN_TRUE;
1360 else
1361 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001362}
1363
Tal Einat6dc57e22018-06-30 23:02:48 +03001364/*[clinic input]
1365select.epoll.fileno
1366
1367Return the epoll control file descriptor.
1368[clinic start generated code]*/
1369
1370static PyObject *
1371select_epoll_fileno_impl(pyEpoll_Object *self)
1372/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 if (self->epfd < 0)
1375 return pyepoll_err_closed();
1376 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377}
1378
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379
Tal Einat6dc57e22018-06-30 23:02:48 +03001380/*[clinic input]
1381@classmethod
1382select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383
Tal Einat6dc57e22018-06-30 23:02:48 +03001384 fd: int
1385 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386
Tal Einat6dc57e22018-06-30 23:02:48 +03001387Create an epoll object from a given control fd.
1388[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389
1390static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001391select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1392/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1393{
1394 SOCKET s_fd = (SOCKET)fd;
1395 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1396}
1397
1398
1399static PyObject *
1400pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 struct epoll_event ev;
1403 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 if (epfd < 0)
1406 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001407
Guido van Rossumee07b942013-12-06 17:46:22 -08001408 switch (op) {
1409 case EPOLL_CTL_ADD:
1410 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 ev.events = events;
1412 ev.data.fd = fd;
1413 Py_BEGIN_ALLOW_THREADS
1414 result = epoll_ctl(epfd, op, fd, &ev);
1415 Py_END_ALLOW_THREADS
1416 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001417 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1419 * operation required a non-NULL pointer in event, even
1420 * though this argument is ignored. */
1421 Py_BEGIN_ALLOW_THREADS
1422 result = epoll_ctl(epfd, op, fd, &ev);
1423 if (errno == EBADF) {
1424 /* fd already closed */
1425 result = 0;
1426 errno = 0;
1427 }
1428 Py_END_ALLOW_THREADS
1429 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001430 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 result = -1;
1432 errno = EINVAL;
1433 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001436 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 return NULL;
1438 }
1439 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001440}
1441
Tal Einat6dc57e22018-06-30 23:02:48 +03001442/*[clinic input]
1443select.epoll.register
1444
1445 fd: fildes
1446 the target file descriptor of the operation
1447 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1448 a bit set composed of the various EPOLL constants
1449
1450Registers a new fd or raises an OSError if the fd is already registered.
1451
1452The epoll interface supports all file descriptors that support poll.
1453[clinic start generated code]*/
1454
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001456select_epoll_register_impl(pyEpoll_Object *self, int fd,
1457 unsigned int eventmask)
1458/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001459{
Tal Einat6dc57e22018-06-30 23:02:48 +03001460 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461}
1462
Tal Einat6dc57e22018-06-30 23:02:48 +03001463/*[clinic input]
1464select.epoll.modify
1465
1466 fd: fildes
1467 the target file descriptor of the operation
1468 eventmask: unsigned_int(bitwise=True)
1469 a bit set composed of the various EPOLL constants
1470
1471Modify event mask for a registered file descriptor.
1472[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001473
1474static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001475select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1476 unsigned int eventmask)
1477/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478{
Tal Einat6dc57e22018-06-30 23:02:48 +03001479 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480}
1481
Tal Einat6dc57e22018-06-30 23:02:48 +03001482/*[clinic input]
1483select.epoll.unregister
1484
1485 fd: fildes
1486 the target file descriptor of the operation
1487
1488Remove a registered file descriptor from the epoll object.
1489[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001490
1491static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001492select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1493/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001494{
Tal Einat6dc57e22018-06-30 23:02:48 +03001495 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001496}
1497
Tal Einat6dc57e22018-06-30 23:02:48 +03001498/*[clinic input]
1499select.epoll.poll
1500
1501 timeout as timeout_obj: object = None
1502 the maximum time to wait in seconds (as float);
1503 a timeout of None or -1 makes poll wait indefinitely
1504 maxevents: int = -1
1505 the maximum number of events returned; -1 means no limit
1506
1507Wait for events on the epoll file descriptor.
1508
1509Returns a list containing any descriptors that have events to report,
1510as a list of (fd, events) 2-tuples.
1511[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001512
1513static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001514select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1515 int maxevents)
1516/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 int nfds, i;
1519 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001520 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001521 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 if (self->epfd < 0)
1524 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001525
Tal Einat6dc57e22018-06-30 23:02:48 +03001526 if (timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001528 ms = -1;
1529 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 }
1531 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001532 /* epoll_wait() has a resolution of 1 millisecond, round towards
1533 infinity to wait at least timeout seconds. */
1534 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001535 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001536 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1537 PyErr_SetString(PyExc_TypeError,
1538 "timeout must be an integer or None");
1539 }
1540 return NULL;
1541 }
1542
1543 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1544 if (ms < INT_MIN || ms > INT_MAX) {
1545 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1546 return NULL;
1547 }
1548
1549 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001553 maxevents = FD_SETSIZE-1;
1554 }
1555 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 PyErr_Format(PyExc_ValueError,
1557 "maxevents must be greater than 0, got %d",
1558 maxevents);
1559 return NULL;
1560 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001561
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001562 evs = PyMem_New(struct epoll_event, maxevents);
1563 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001564 PyErr_NoMemory();
1565 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001567
Victor Stinner41eba222015-03-30 21:59:21 +02001568 do {
1569 Py_BEGIN_ALLOW_THREADS
1570 errno = 0;
1571 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1572 Py_END_ALLOW_THREADS
1573
1574 if (errno != EINTR)
1575 break;
1576
1577 /* poll() was interrupted by a signal */
1578 if (PyErr_CheckSignals())
1579 goto error;
1580
1581 if (timeout >= 0) {
1582 timeout = deadline - _PyTime_GetMonotonicClock();
1583 if (timeout < 0) {
1584 nfds = 0;
1585 break;
1586 }
1587 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1588 /* retry epoll_wait() with the recomputed timeout */
1589 }
1590 } while(1);
1591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001593 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 goto error;
1595 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 elist = PyList_New(nfds);
1598 if (elist == NULL) {
1599 goto error;
1600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001603 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 if (etuple == NULL) {
1605 Py_CLEAR(elist);
1606 goto error;
1607 }
1608 PyList_SET_ITEM(elist, i, etuple);
1609 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001610
Christian Heimesf6cd9672008-03-26 13:45:42 +00001611 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001612 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001614}
1615
Tal Einat6dc57e22018-06-30 23:02:48 +03001616
1617/*[clinic input]
1618select.epoll.__enter__
1619
1620[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001621
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001622static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001623select_epoll___enter___impl(pyEpoll_Object *self)
1624/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001625{
1626 if (self->epfd < 0)
1627 return pyepoll_err_closed();
1628
1629 Py_INCREF(self);
1630 return (PyObject *)self;
1631}
1632
Tal Einat6dc57e22018-06-30 23:02:48 +03001633/*[clinic input]
1634select.epoll.__exit__
1635
1636 exc_type: object = None
1637 exc_value: object = None
1638 exc_tb: object = None
1639 /
1640
1641[clinic start generated code]*/
1642
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001643static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001644select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1645 PyObject *exc_value, PyObject *exc_tb)
1646/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001647{
1648 _Py_IDENTIFIER(close);
1649
Tal Einat6dc57e22018-06-30 23:02:48 +03001650 return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001651}
1652
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001653static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 {"closed", (getter)pyepoll_get_closed, NULL,
1655 "True if the epoll handler is closed"},
1656 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001657};
1658
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001659#endif /* HAVE_EPOLL */
1660
1661#ifdef HAVE_KQUEUE
1662/* **************************************************************************
1663 * kqueue interface for BSD
1664 *
1665 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1666 * All rights reserved.
1667 *
1668 * Redistribution and use in source and binary forms, with or without
1669 * modification, are permitted provided that the following conditions
1670 * are met:
1671 * 1. Redistributions of source code must retain the above copyright
1672 * notice, this list of conditions and the following disclaimer.
1673 * 2. Redistributions in binary form must reproduce the above copyright
1674 * notice, this list of conditions and the following disclaimer in the
1675 * documentation and/or other materials provided with the distribution.
1676 *
1677 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1678 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1679 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1680 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1681 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1682 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1683 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1684 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1685 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1686 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1687 * SUCH DAMAGE.
1688 */
1689
1690#ifdef HAVE_SYS_EVENT_H
1691#include <sys/event.h>
1692#endif
1693
1694PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001695"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001696\n\
1697This object is the equivalent of the struct kevent for the C API.\n\
1698\n\
1699See the kqueue manpage for more detailed information about the meaning\n\
1700of the arguments.\n\
1701\n\
1702One minor note: while you might hope that udata could store a\n\
1703reference to a python object, it cannot, because it is impossible to\n\
1704keep a proper reference count of the object once it's passed into the\n\
1705kernel. Therefore, I have restricted it to only storing an integer. I\n\
1706recommend ignoring it and simply using the 'ident' field to key off\n\
1707of. You could also set up a dictionary on the python side to store a\n\
1708udata->object mapping.");
1709
1710typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 PyObject_HEAD
1712 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001713} kqueue_event_Object;
1714
1715static PyTypeObject kqueue_event_Type;
1716
1717#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1718
1719typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 PyObject_HEAD
1721 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001722} kqueue_queue_Object;
1723
1724static PyTypeObject kqueue_queue_Type;
1725
1726#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1727
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001728#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1729# error uintptr_t does not match void *!
1730#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1731# define T_UINTPTRT T_ULONGLONG
1732# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001733# define UINTPTRT_FMT_UNIT "K"
1734# define INTPTRT_FMT_UNIT "L"
1735#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1736# define T_UINTPTRT T_ULONG
1737# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001738# define UINTPTRT_FMT_UNIT "k"
1739# define INTPTRT_FMT_UNIT "l"
1740#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1741# define T_UINTPTRT T_UINT
1742# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001743# define UINTPTRT_FMT_UNIT "I"
1744# define INTPTRT_FMT_UNIT "i"
1745#else
1746# error uintptr_t does not match int, long, or long long!
1747#endif
1748
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001749#if SIZEOF_LONG_LONG == 8
1750# define T_INT64 T_LONGLONG
1751# define INT64_FMT_UNIT "L"
1752#elif SIZEOF_LONG == 8
1753# define T_INT64 T_LONG
1754# define INT64_FMT_UNIT "l"
1755#elif SIZEOF_INT == 8
1756# define T_INT64 T_INT
1757# define INT64_FMT_UNIT "i"
1758#else
1759# define INT64_FMT_UNIT "_"
1760#endif
1761
1762#if SIZEOF_LONG_LONG == 4
1763# define T_UINT32 T_ULONGLONG
1764# define UINT32_FMT_UNIT "K"
1765#elif SIZEOF_LONG == 4
1766# define T_UINT32 T_ULONG
1767# define UINT32_FMT_UNIT "k"
1768#elif SIZEOF_INT == 4
1769# define T_UINT32 T_UINT
1770# define UINT32_FMT_UNIT "I"
1771#else
1772# define UINT32_FMT_UNIT "_"
1773#endif
1774
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001775/*
1776 * kevent is not standard and its members vary across BSDs.
1777 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001778#ifdef __NetBSD__
1779# define FILTER_TYPE T_UINT32
1780# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1781# define FLAGS_TYPE T_UINT32
1782# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1783# define FFLAGS_TYPE T_UINT32
1784# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001785#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001786# define FILTER_TYPE T_SHORT
1787# define FILTER_FMT_UNIT "h"
1788# define FLAGS_TYPE T_USHORT
1789# define FLAGS_FMT_UNIT "H"
1790# define FFLAGS_TYPE T_UINT
1791# define FFLAGS_FMT_UNIT "I"
1792#endif
1793
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001794#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001795# define DATA_TYPE T_INT64
1796# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001797#else
1798# define DATA_TYPE T_INTPTRT
1799# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001800#endif
1801
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001802/* Unfortunately, we can't store python objects in udata, because
1803 * kevents in the kernel can be removed without warning, which would
1804 * forever lose the refcount on the object stored with it.
1805 */
1806
1807#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1808static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001809 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1810 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1811 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001813 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1815 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001816};
1817#undef KQ_OFF
1818
1819static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001820
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001821kqueue_event_repr(kqueue_event_Object *s)
1822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 char buf[1024];
1824 PyOS_snprintf(
1825 buf, sizeof(buf),
1826 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001827 "data=0x%llx udata=%p>",
1828 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1829 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831}
1832
1833static int
1834kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 PyObject *pfd;
1837 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1838 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001839 static const char fmt[] = "O|"
1840 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1841 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1846 &pfd, &(self->e.filter), &(self->e.flags),
1847 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1848 return -1;
1849 }
1850
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001851 if (PyLong_Check(pfd)) {
1852 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 }
1854 else {
1855 self->e.ident = PyObject_AsFileDescriptor(pfd);
1856 }
1857 if (PyErr_Occurred()) {
1858 return -1;
1859 }
1860 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001861}
1862
1863static PyObject *
1864kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001866{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001867 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001870 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001872
1873#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1874 result = CMP(s->e.ident, o->e.ident)
1875 : CMP(s->e.filter, o->e.filter)
1876 : CMP(s->e.flags, o->e.flags)
1877 : CMP(s->e.fflags, o->e.fflags)
1878 : CMP(s->e.data, o->e.data)
1879 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1880 : 0;
1881#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001882
stratakise8b19652017-11-02 11:32:54 +01001883 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001884}
1885
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001886static PyObject *
1887kqueue_queue_err_closed(void)
1888{
Victor Stinner13423c32013-08-22 00:19:50 +02001889 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891}
1892
1893static int
1894kqueue_queue_internal_close(kqueue_queue_Object *self)
1895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 int save_errno = 0;
1897 if (self->kqfd >= 0) {
1898 int kqfd = self->kqfd;
1899 self->kqfd = -1;
1900 Py_BEGIN_ALLOW_THREADS
1901 if (close(kqfd) < 0)
1902 save_errno = errno;
1903 Py_END_ALLOW_THREADS
1904 }
1905 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001906}
1907
1908static PyObject *
1909newKqueue_Object(PyTypeObject *type, SOCKET fd)
1910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 kqueue_queue_Object *self;
1912 assert(type != NULL && type->tp_alloc != NULL);
1913 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1914 if (self == NULL) {
1915 return NULL;
1916 }
1917
1918 if (fd == -1) {
1919 Py_BEGIN_ALLOW_THREADS
1920 self->kqfd = kqueue();
1921 Py_END_ALLOW_THREADS
1922 }
1923 else {
1924 self->kqfd = fd;
1925 }
1926 if (self->kqfd < 0) {
1927 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001928 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 return NULL;
1930 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001931
1932 if (fd == -1) {
1933 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1934 Py_DECREF(self);
1935 return NULL;
1936 }
1937 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001939}
1940
Tal Einat6dc57e22018-06-30 23:02:48 +03001941/*[clinic input]
1942@classmethod
1943select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001944
Tal Einat6dc57e22018-06-30 23:02:48 +03001945Kqueue syscall wrapper.
1946
1947For example, to start watching a socket for input:
1948>>> kq = kqueue()
1949>>> sock = socket()
1950>>> sock.connect((host, port))
1951>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1952
1953To wait one second for it to become writeable:
1954>>> kq.control(None, 1, 1000)
1955
1956To stop listening:
1957>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1958[clinic start generated code]*/
1959
1960static PyObject *
1961select_kqueue_impl(PyTypeObject *type)
1962/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001965}
1966
1967static void
1968kqueue_queue_dealloc(kqueue_queue_Object *self)
1969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 kqueue_queue_internal_close(self);
1971 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001972}
1973
Tal Einat6dc57e22018-06-30 23:02:48 +03001974/*[clinic input]
1975select.kqueue.close
1976
1977Close the kqueue control file descriptor.
1978
1979Further operations on the kqueue object will raise an exception.
1980[clinic start generated code]*/
1981
1982static PyObject *
1983select_kqueue_close_impl(kqueue_queue_Object *self)
1984/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 errno = kqueue_queue_internal_close(self);
1987 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001988 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 return NULL;
1990 }
1991 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001992}
1993
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001994static PyObject*
1995kqueue_queue_get_closed(kqueue_queue_Object *self)
1996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 if (self->kqfd < 0)
1998 Py_RETURN_TRUE;
1999 else
2000 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002001}
2002
Tal Einat6dc57e22018-06-30 23:02:48 +03002003/*[clinic input]
2004select.kqueue.fileno
2005
2006Return the kqueue control file descriptor.
2007[clinic start generated code]*/
2008
2009static PyObject *
2010select_kqueue_fileno_impl(kqueue_queue_Object *self)
2011/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 if (self->kqfd < 0)
2014 return kqueue_queue_err_closed();
2015 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002016}
2017
Tal Einat6dc57e22018-06-30 23:02:48 +03002018/*[clinic input]
2019@classmethod
2020select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002021
Tal Einat6dc57e22018-06-30 23:02:48 +03002022 fd: int
2023 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002024
Tal Einat6dc57e22018-06-30 23:02:48 +03002025Create a kqueue object from a given control fd.
2026[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002027
2028static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002029select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2030/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002031{
Tal Einat6dc57e22018-06-30 23:02:48 +03002032 SOCKET s_fd = (SOCKET)fd;
2033
2034 return newKqueue_Object(type, s_fd);
2035}
2036
2037/*[clinic input]
2038select.kqueue.control
2039
2040 changelist: object
2041 Must be an iterable of kevent objects describing the changes to be made
2042 to the kernel's watch list or None.
2043 maxevents: int
2044 The maximum number of events that the kernel will return.
2045 timeout as otimeout: object = None
2046 The maximum time to wait in seconds, or else None to wait forever.
2047 This accepts floats for smaller timeouts, too.
2048 /
2049
2050Calls the kernel kevent function.
2051[clinic start generated code]*/
2052
2053static PyObject *
2054select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2055 int maxevents, PyObject *otimeout)
2056/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 int gotevents = 0;
2059 int nchanges = 0;
2060 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002061 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 PyObject *result = NULL;
2063 struct kevent *evl = NULL;
2064 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002065 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002067 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 if (self->kqfd < 0)
2070 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002071
Tal Einat6dc57e22018-06-30 23:02:48 +03002072 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 PyErr_Format(PyExc_ValueError,
2074 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002075 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 return NULL;
2077 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002078
Tal Einat6dc57e22018-06-30 23:02:48 +03002079 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 ptimeoutspec = NULL;
2081 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002082 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002083 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002084 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002085 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002086 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002087 "or None, got %.200s",
2088 Py_TYPE(otimeout)->tp_name);
2089 return NULL;
2090 }
2091
Victor Stinner4448c082015-03-31 11:48:34 +02002092 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002093 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002094
Victor Stinner4448c082015-03-31 11:48:34 +02002095 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 PyErr_SetString(PyExc_ValueError,
2097 "timeout must be positive or None");
2098 return NULL;
2099 }
Victor Stinner4448c082015-03-31 11:48:34 +02002100 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002102
Tal Einat6dc57e22018-06-30 23:02:48 +03002103 if (changelist != Py_None) {
2104 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002105 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 return NULL;
2107 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002108 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2109 PyErr_SetString(PyExc_OverflowError,
2110 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 goto error;
2112 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002113 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 chl = PyMem_New(struct kevent, nchanges);
2116 if (chl == NULL) {
2117 PyErr_NoMemory();
2118 goto error;
2119 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002120 for (i = 0; i < nchanges; ++i) {
2121 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 PyErr_SetString(PyExc_TypeError,
2124 "changelist must be an iterable of "
2125 "select.kevent objects");
2126 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002128 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002130 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002134 if (maxevents) {
2135 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 if (evl == NULL) {
2137 PyErr_NoMemory();
2138 goto error;
2139 }
2140 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002141
Victor Stinner4448c082015-03-31 11:48:34 +02002142 if (ptimeoutspec)
2143 deadline = _PyTime_GetMonotonicClock() + timeout;
2144
2145 do {
2146 Py_BEGIN_ALLOW_THREADS
2147 errno = 0;
2148 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002149 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002150 Py_END_ALLOW_THREADS
2151
2152 if (errno != EINTR)
2153 break;
2154
2155 /* kevent() was interrupted by a signal */
2156 if (PyErr_CheckSignals())
2157 goto error;
2158
2159 if (ptimeoutspec) {
2160 timeout = deadline - _PyTime_GetMonotonicClock();
2161 if (timeout < 0) {
2162 gotevents = 0;
2163 break;
2164 }
2165 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2166 goto error;
2167 /* retry kevent() with the recomputed timeout */
2168 }
2169 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 if (gotevents == -1) {
2172 PyErr_SetFromErrno(PyExc_OSError);
2173 goto error;
2174 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 result = PyList_New(gotevents);
2177 if (result == NULL) {
2178 goto error;
2179 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 for (i = 0; i < gotevents; i++) {
2182 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2185 if (ch == NULL) {
2186 goto error;
2187 }
2188 ch->e = evl[i];
2189 PyList_SET_ITEM(result, i, (PyObject *)ch);
2190 }
2191 PyMem_Free(chl);
2192 PyMem_Free(evl);
2193 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002194
2195 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 PyMem_Free(chl);
2197 PyMem_Free(evl);
2198 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002199 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002201}
2202
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002203static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 {"closed", (getter)kqueue_queue_get_closed, NULL,
2205 "True if the kqueue handler is closed"},
2206 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002207};
2208
Tal Einat6dc57e22018-06-30 23:02:48 +03002209#endif /* HAVE_KQUEUE */
2210
2211
2212/* ************************************************************************ */
2213
2214#include "clinic/selectmodule.c.h"
2215
2216#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2217
2218static PyMethodDef poll_methods[] = {
2219 SELECT_POLL_REGISTER_METHODDEF
2220 SELECT_POLL_MODIFY_METHODDEF
2221 SELECT_POLL_UNREGISTER_METHODDEF
2222 SELECT_POLL_POLL_METHODDEF
2223 {NULL, NULL} /* sentinel */
2224};
2225
2226static PyTypeObject poll_Type = {
2227 /* The ob_type field must be initialized in the module init function
2228 * to be portable to Windows without using C++. */
2229 PyVarObject_HEAD_INIT(NULL, 0)
2230 "select.poll", /*tp_name*/
2231 sizeof(pollObject), /*tp_basicsize*/
2232 0, /*tp_itemsize*/
2233 /* methods */
2234 (destructor)poll_dealloc, /*tp_dealloc*/
2235 0, /*tp_print*/
2236 0, /*tp_getattr*/
2237 0, /*tp_setattr*/
2238 0, /*tp_reserved*/
2239 0, /*tp_repr*/
2240 0, /*tp_as_number*/
2241 0, /*tp_as_sequence*/
2242 0, /*tp_as_mapping*/
2243 0, /*tp_hash*/
2244 0, /*tp_call*/
2245 0, /*tp_str*/
2246 0, /*tp_getattro*/
2247 0, /*tp_setattro*/
2248 0, /*tp_as_buffer*/
2249 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2250 0, /*tp_doc*/
2251 0, /*tp_traverse*/
2252 0, /*tp_clear*/
2253 0, /*tp_richcompare*/
2254 0, /*tp_weaklistoffset*/
2255 0, /*tp_iter*/
2256 0, /*tp_iternext*/
2257 poll_methods, /*tp_methods*/
2258};
2259
2260#ifdef HAVE_SYS_DEVPOLL_H
2261
2262static PyMethodDef devpoll_methods[] = {
2263 SELECT_DEVPOLL_REGISTER_METHODDEF
2264 SELECT_DEVPOLL_MODIFY_METHODDEF
2265 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2266 SELECT_DEVPOLL_POLL_METHODDEF
2267 SELECT_DEVPOLL_CLOSE_METHODDEF
2268 SELECT_DEVPOLL_FILENO_METHODDEF
2269 {NULL, NULL} /* sentinel */
2270};
2271
2272static PyTypeObject devpoll_Type = {
2273 /* The ob_type field must be initialized in the module init function
2274 * to be portable to Windows without using C++. */
2275 PyVarObject_HEAD_INIT(NULL, 0)
2276 "select.devpoll", /*tp_name*/
2277 sizeof(devpollObject), /*tp_basicsize*/
2278 0, /*tp_itemsize*/
2279 /* methods */
2280 (destructor)devpoll_dealloc, /*tp_dealloc*/
2281 0, /*tp_print*/
2282 0, /*tp_getattr*/
2283 0, /*tp_setattr*/
2284 0, /*tp_reserved*/
2285 0, /*tp_repr*/
2286 0, /*tp_as_number*/
2287 0, /*tp_as_sequence*/
2288 0, /*tp_as_mapping*/
2289 0, /*tp_hash*/
2290 0, /*tp_call*/
2291 0, /*tp_str*/
2292 0, /*tp_getattro*/
2293 0, /*tp_setattro*/
2294 0, /*tp_as_buffer*/
2295 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2296 0, /*tp_doc*/
2297 0, /*tp_traverse*/
2298 0, /*tp_clear*/
2299 0, /*tp_richcompare*/
2300 0, /*tp_weaklistoffset*/
2301 0, /*tp_iter*/
2302 0, /*tp_iternext*/
2303 devpoll_methods, /*tp_methods*/
2304 0, /* tp_members */
2305 devpoll_getsetlist, /* tp_getset */
2306};
2307
2308#endif /* HAVE_SYS_DEVPOLL_H */
2309
2310#endif /* HAVE_POLL */
2311
2312#ifdef HAVE_EPOLL
2313
2314static PyMethodDef pyepoll_methods[] = {
2315 SELECT_EPOLL_FROMFD_METHODDEF
2316 SELECT_EPOLL_CLOSE_METHODDEF
2317 SELECT_EPOLL_FILENO_METHODDEF
2318 SELECT_EPOLL_MODIFY_METHODDEF
2319 SELECT_EPOLL_REGISTER_METHODDEF
2320 SELECT_EPOLL_UNREGISTER_METHODDEF
2321 SELECT_EPOLL_POLL_METHODDEF
2322 SELECT_EPOLL___ENTER___METHODDEF
2323 SELECT_EPOLL___EXIT___METHODDEF
2324 {NULL, NULL},
2325};
2326
2327static PyTypeObject pyEpoll_Type = {
2328 PyVarObject_HEAD_INIT(NULL, 0)
2329 "select.epoll", /* tp_name */
2330 sizeof(pyEpoll_Object), /* tp_basicsize */
2331 0, /* tp_itemsize */
2332 (destructor)pyepoll_dealloc, /* tp_dealloc */
2333 0, /* tp_print */
2334 0, /* tp_getattr */
2335 0, /* tp_setattr */
2336 0, /* tp_reserved */
2337 0, /* tp_repr */
2338 0, /* tp_as_number */
2339 0, /* tp_as_sequence */
2340 0, /* tp_as_mapping */
2341 0, /* tp_hash */
2342 0, /* tp_call */
2343 0, /* tp_str */
2344 PyObject_GenericGetAttr, /* tp_getattro */
2345 0, /* tp_setattro */
2346 0, /* tp_as_buffer */
2347 Py_TPFLAGS_DEFAULT, /* tp_flags */
2348 select_epoll__doc__, /* tp_doc */
2349 0, /* tp_traverse */
2350 0, /* tp_clear */
2351 0, /* tp_richcompare */
2352 0, /* tp_weaklistoffset */
2353 0, /* tp_iter */
2354 0, /* tp_iternext */
2355 pyepoll_methods, /* tp_methods */
2356 0, /* tp_members */
2357 pyepoll_getsetlist, /* tp_getset */
2358 0, /* tp_base */
2359 0, /* tp_dict */
2360 0, /* tp_descr_get */
2361 0, /* tp_descr_set */
2362 0, /* tp_dictoffset */
2363 0, /* tp_init */
2364 0, /* tp_alloc */
2365 select_epoll, /* tp_new */
2366 0, /* tp_free */
2367};
2368
2369#endif /* HAVE_EPOLL */
2370
2371#ifdef HAVE_KQUEUE
2372
2373static PyTypeObject kqueue_event_Type = {
2374 PyVarObject_HEAD_INIT(NULL, 0)
2375 "select.kevent", /* tp_name */
2376 sizeof(kqueue_event_Object), /* tp_basicsize */
2377 0, /* tp_itemsize */
2378 0, /* tp_dealloc */
2379 0, /* tp_print */
2380 0, /* tp_getattr */
2381 0, /* tp_setattr */
2382 0, /* tp_reserved */
2383 (reprfunc)kqueue_event_repr, /* tp_repr */
2384 0, /* tp_as_number */
2385 0, /* tp_as_sequence */
2386 0, /* tp_as_mapping */
2387 0, /* tp_hash */
2388 0, /* tp_call */
2389 0, /* tp_str */
2390 0, /* tp_getattro */
2391 0, /* tp_setattro */
2392 0, /* tp_as_buffer */
2393 Py_TPFLAGS_DEFAULT, /* tp_flags */
2394 kqueue_event_doc, /* tp_doc */
2395 0, /* tp_traverse */
2396 0, /* tp_clear */
2397 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
2398 0, /* tp_weaklistoffset */
2399 0, /* tp_iter */
2400 0, /* tp_iternext */
2401 0, /* tp_methods */
2402 kqueue_event_members, /* tp_members */
2403 0, /* tp_getset */
2404 0, /* tp_base */
2405 0, /* tp_dict */
2406 0, /* tp_descr_get */
2407 0, /* tp_descr_set */
2408 0, /* tp_dictoffset */
2409 (initproc)kqueue_event_init, /* tp_init */
2410 0, /* tp_alloc */
2411 0, /* tp_new */
2412 0, /* tp_free */
2413};
2414
2415static PyMethodDef kqueue_queue_methods[] = {
2416 SELECT_KQUEUE_FROMFD_METHODDEF
2417 SELECT_KQUEUE_CLOSE_METHODDEF
2418 SELECT_KQUEUE_FILENO_METHODDEF
2419 SELECT_KQUEUE_CONTROL_METHODDEF
2420 {NULL, NULL},
2421};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002422
2423static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 PyVarObject_HEAD_INIT(NULL, 0)
2425 "select.kqueue", /* tp_name */
2426 sizeof(kqueue_queue_Object), /* tp_basicsize */
2427 0, /* tp_itemsize */
2428 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2429 0, /* tp_print */
2430 0, /* tp_getattr */
2431 0, /* tp_setattr */
2432 0, /* tp_reserved */
2433 0, /* tp_repr */
2434 0, /* tp_as_number */
2435 0, /* tp_as_sequence */
2436 0, /* tp_as_mapping */
2437 0, /* tp_hash */
2438 0, /* tp_call */
2439 0, /* tp_str */
2440 0, /* tp_getattro */
2441 0, /* tp_setattro */
2442 0, /* tp_as_buffer */
2443 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tal Einat6dc57e22018-06-30 23:02:48 +03002444 select_kqueue__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 0, /* tp_traverse */
2446 0, /* tp_clear */
2447 0, /* tp_richcompare */
2448 0, /* tp_weaklistoffset */
2449 0, /* tp_iter */
2450 0, /* tp_iternext */
2451 kqueue_queue_methods, /* tp_methods */
2452 0, /* tp_members */
2453 kqueue_queue_getsetlist, /* tp_getset */
2454 0, /* tp_base */
2455 0, /* tp_dict */
2456 0, /* tp_descr_get */
2457 0, /* tp_descr_set */
2458 0, /* tp_dictoffset */
2459 0, /* tp_init */
2460 0, /* tp_alloc */
Tal Einat6dc57e22018-06-30 23:02:48 +03002461 select_kqueue, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002463};
2464
2465#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002466
2467
2468
2469
2470
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002471/* ************************************************************************ */
2472
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002473
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002474static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002475 SELECT_SELECT_METHODDEF
2476 SELECT_POLL_METHODDEF
2477 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002479};
2480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002481PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002482"This module supports asynchronous I/O on multiple file descriptors.\n\
2483\n\
2484*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002485On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002486
Martin v. Löwis1a214512008-06-11 05:26:20 +00002487
2488static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 PyModuleDef_HEAD_INIT,
2490 "select",
2491 module_doc,
2492 -1,
2493 select_methods,
2494 NULL,
2495 NULL,
2496 NULL,
2497 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002498};
2499
Jesus Cead8b9ae62011-11-14 19:07:41 +01002500
2501
2502
Mark Hammond62b1ab12002-07-23 06:31:15 +00002503PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002504PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 PyObject *m;
2507 m = PyModule_Create(&selectmodule);
2508 if (m == NULL)
2509 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002510
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002511 Py_INCREF(PyExc_OSError);
2512 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002513
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002514#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002515#ifdef HAVE_BROKEN_PIPE_BUF
2516#undef PIPE_BUF
2517#define PIPE_BUF 512
2518#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002519 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002520#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002521
Charles-François Natali986a56c2013-01-19 12:19:10 +01002522#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002523#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 if (select_have_broken_poll()) {
2525 if (PyObject_DelAttrString(m, "poll") == -1) {
2526 PyErr_Clear();
2527 }
2528 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002529#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002531#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002532 if (PyType_Ready(&poll_Type) < 0)
2533 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002534 PyModule_AddIntMacro(m, POLLIN);
2535 PyModule_AddIntMacro(m, POLLPRI);
2536 PyModule_AddIntMacro(m, POLLOUT);
2537 PyModule_AddIntMacro(m, POLLERR);
2538 PyModule_AddIntMacro(m, POLLHUP);
2539 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002540
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002541#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002542 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002543#endif
2544#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002545 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002546#endif
2547#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002548 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002549#endif
2550#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002551 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002552#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002553#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002554 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002555#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002556#ifdef POLLRDHUP
2557 /* Kernel 2.6.17+ */
2558 PyModule_AddIntMacro(m, POLLRDHUP);
2559#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002561#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002562
Jesus Cead8b9ae62011-11-14 19:07:41 +01002563#ifdef HAVE_SYS_DEVPOLL_H
2564 if (PyType_Ready(&devpoll_Type) < 0)
2565 return NULL;
2566#endif
2567
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002568#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2570 if (PyType_Ready(&pyEpoll_Type) < 0)
2571 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 Py_INCREF(&pyEpoll_Type);
2574 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002575
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002576 PyModule_AddIntMacro(m, EPOLLIN);
2577 PyModule_AddIntMacro(m, EPOLLOUT);
2578 PyModule_AddIntMacro(m, EPOLLPRI);
2579 PyModule_AddIntMacro(m, EPOLLERR);
2580 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002581#ifdef EPOLLRDHUP
2582 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002583 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002584#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002585 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002586#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002588 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002589#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002590#ifdef EPOLLEXCLUSIVE
2591 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2592#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002593
2594#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002595 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002596#endif
2597#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002598 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002599#endif
2600#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002601 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002602#endif
2603#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002604 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002605#endif
2606#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002607 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002608#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002609
Benjamin Peterson95c16622011-12-27 15:36:32 -06002610#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002611 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002612#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002613#endif /* HAVE_EPOLL */
2614
2615#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 kqueue_event_Type.tp_new = PyType_GenericNew;
2617 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2618 if(PyType_Ready(&kqueue_event_Type) < 0)
2619 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 Py_INCREF(&kqueue_event_Type);
2622 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2625 if(PyType_Ready(&kqueue_queue_Type) < 0)
2626 return NULL;
2627 Py_INCREF(&kqueue_queue_Type);
2628 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2629
2630 /* event filters */
2631 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2632 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002633#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002635#endif
2636#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002638#endif
2639#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002641#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002642#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002644#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002645#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002647#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002648 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 /* event flags */
2651 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2652 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2653 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2654 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2655 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2656 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002657
Berker Peksag7ec64562016-09-14 18:16:59 +03002658#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002660#endif
2661#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002663#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2666 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002669#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002671#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002674#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2676 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2677 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2678 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2679 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2680 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2681 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002682#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002685#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2687 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2688 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2689 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2690 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2693 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2694 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002695#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696
2697 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002698#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002699 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2700 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2701 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002702#endif
2703
2704#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002705 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002706}