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