blob: 15aca2724a2ca01fb51ed5fff13346da8076caeb [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 +0100849static PyObject *
850devpoll_modify(devpollObject *self, PyObject *args)
851{
Tal Einat6dc57e22018-06-30 23:02:48 +0300852 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100853}
854
Tal Einat6dc57e22018-06-30 23:02:48 +0300855/*[clinic input]
856select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100857
Tal Einat6dc57e22018-06-30 23:02:48 +0300858 fd: fildes
859 /
860
861Remove a file descriptor being tracked by the polling object.
862[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863
864static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300865select_devpoll_unregister_impl(devpollObject *self, int fd)
866/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100867{
Victor Stinner13423c32013-08-22 00:19:50 +0200868 if (self->fd_devpoll < 0)
869 return devpoll_err_closed();
870
Jesus Cead8b9ae62011-11-14 19:07:41 +0100871 self->fds[self->n_fds].fd = fd;
872 self->fds[self->n_fds].events = POLLREMOVE;
873
874 if (++self->n_fds == self->max_n_fds) {
875 if (devpoll_flush(self))
876 return NULL;
877 }
878
879 Py_RETURN_NONE;
880}
881
Tal Einat6dc57e22018-06-30 23:02:48 +0300882/*[clinic input]
883select.devpoll.poll
884 timeout as timeout_obj: object = None
885 /
886
887Polls the set of registered file descriptors.
888
889Returns a list containing any descriptors that have events or errors to
890report, as a list of (fd, event) 2-tuples.
891[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100892
893static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300894select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
895/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100896{
897 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200898 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100899 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100900 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200901 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902
Victor Stinner13423c32013-08-22 00:19:50 +0200903 if (self->fd_devpoll < 0)
904 return devpoll_err_closed();
905
Jesus Cead8b9ae62011-11-14 19:07:41 +0100906 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300907 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100908 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200909 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100910 }
911 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200912 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100913 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200914 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
915 PyErr_SetString(PyExc_TypeError,
916 "timeout must be an integer or None");
917 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100918 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200919 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920
Pablo Galindo2c15b292017-10-17 15:14:41 +0100921 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200922 if (ms < -1 || ms > INT_MAX) {
923 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
924 return NULL;
925 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100926 }
927
928 if (devpoll_flush(self))
929 return NULL;
930
931 dvp.dp_fds = self->fds;
932 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200933 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100934
Victor Stinner45ca48b2015-03-31 12:10:33 +0200935 if (timeout >= 0)
936 deadline = _PyTime_GetMonotonicClock() + timeout;
937
938 do {
939 /* call devpoll() */
940 Py_BEGIN_ALLOW_THREADS
941 errno = 0;
942 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
943 Py_END_ALLOW_THREADS
944
945 if (errno != EINTR)
946 break;
947
948 /* devpoll() was interrupted by a signal */
949 if (PyErr_CheckSignals())
950 return NULL;
951
952 if (timeout >= 0) {
953 timeout = deadline - _PyTime_GetMonotonicClock();
954 if (timeout < 0) {
955 poll_result = 0;
956 break;
957 }
958 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
959 dvp.dp_timeout = (int)ms;
960 /* retry devpoll() with the recomputed timeout */
961 }
962 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100963
964 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300965 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100966 return NULL;
967 }
968
969 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100970 result_list = PyList_New(poll_result);
971 if (!result_list)
972 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200973
974 for (i = 0; i < poll_result; i++) {
975 num1 = PyLong_FromLong(self->fds[i].fd);
976 num2 = PyLong_FromLong(self->fds[i].revents);
977 if ((num1 == NULL) || (num2 == NULL)) {
978 Py_XDECREF(num1);
979 Py_XDECREF(num2);
980 goto error;
981 }
982 value = PyTuple_Pack(2, num1, num2);
983 Py_DECREF(num1);
984 Py_DECREF(num2);
985 if (value == NULL)
986 goto error;
987 if ((PyList_SetItem(result_list, i, value)) == -1) {
988 Py_DECREF(value);
989 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100990 }
991 }
992
993 return result_list;
994
995 error:
996 Py_DECREF(result_list);
997 return NULL;
998}
999
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001000static int
1001devpoll_internal_close(devpollObject *self)
1002{
1003 int save_errno = 0;
1004 if (self->fd_devpoll >= 0) {
1005 int fd = self->fd_devpoll;
1006 self->fd_devpoll = -1;
1007 Py_BEGIN_ALLOW_THREADS
1008 if (close(fd) < 0)
1009 save_errno = errno;
1010 Py_END_ALLOW_THREADS
1011 }
1012 return save_errno;
1013}
1014
Tal Einat6dc57e22018-06-30 23:02:48 +03001015/*[clinic input]
1016select.devpoll.close
1017
1018Close the devpoll file descriptor.
1019
1020Further operations on the devpoll object will raise an exception.
1021[clinic start generated code]*/
1022
1023static PyObject *
1024select_devpoll_close_impl(devpollObject *self)
1025/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001026{
1027 errno = devpoll_internal_close(self);
1028 if (errno < 0) {
1029 PyErr_SetFromErrno(PyExc_OSError);
1030 return NULL;
1031 }
1032 Py_RETURN_NONE;
1033}
1034
Victor Stinner13423c32013-08-22 00:19:50 +02001035static PyObject*
1036devpoll_get_closed(devpollObject *self)
1037{
1038 if (self->fd_devpoll < 0)
1039 Py_RETURN_TRUE;
1040 else
1041 Py_RETURN_FALSE;
1042}
1043
Tal Einat6dc57e22018-06-30 23:02:48 +03001044/*[clinic input]
1045select.devpoll.fileno
1046
1047Return the file descriptor.
1048[clinic start generated code]*/
1049
1050static PyObject *
1051select_devpoll_fileno_impl(devpollObject *self)
1052/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001053{
1054 if (self->fd_devpoll < 0)
1055 return devpoll_err_closed();
1056 return PyLong_FromLong(self->fd_devpoll);
1057}
1058
Victor Stinner13423c32013-08-22 00:19:50 +02001059static PyGetSetDef devpoll_getsetlist[] = {
1060 {"closed", (getter)devpoll_get_closed, NULL,
1061 "True if the devpoll object is closed"},
1062 {0},
1063};
1064
Jesus Cead8b9ae62011-11-14 19:07:41 +01001065static devpollObject *
1066newDevPollObject(void)
1067{
1068 devpollObject *self;
1069 int fd_devpoll, limit_result;
1070 struct pollfd *fds;
1071 struct rlimit limit;
1072
Jesus Cead8b9ae62011-11-14 19:07:41 +01001073 /*
1074 ** If we try to process more that getrlimit()
1075 ** fds, the kernel will give an error, so
1076 ** we set the limit here. It is a dynamic
1077 ** value, because we can change rlimit() anytime.
1078 */
1079 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001080 if (limit_result == -1) {
1081 PyErr_SetFromErrno(PyExc_OSError);
1082 return NULL;
1083 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001084
1085 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1086 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001087 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001088
1089 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1090 if (fds == NULL) {
1091 close(fd_devpoll);
1092 PyErr_NoMemory();
1093 return NULL;
1094 }
1095
1096 self = PyObject_New(devpollObject, &devpoll_Type);
1097 if (self == NULL) {
1098 close(fd_devpoll);
1099 PyMem_DEL(fds);
1100 return NULL;
1101 }
1102 self->fd_devpoll = fd_devpoll;
1103 self->max_n_fds = limit.rlim_cur;
1104 self->n_fds = 0;
1105 self->fds = fds;
1106
1107 return self;
1108}
1109
1110static void
1111devpoll_dealloc(devpollObject *self)
1112{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001113 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001114 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001115 PyObject_Del(self);
1116}
1117
Jesus Cead8b9ae62011-11-14 19:07:41 +01001118#endif /* HAVE_SYS_DEVPOLL_H */
1119
1120
Tal Einat6dc57e22018-06-30 23:02:48 +03001121/*[clinic input]
1122select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001123
Tal Einat6dc57e22018-06-30 23:02:48 +03001124Returns a polling object.
1125
1126This object supports registering and unregistering file descriptors, and then
1127polling them for I/O events.
1128[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001129
1130static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001131select_poll_impl(PyObject *module)
1132/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001135}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001136
Jesus Cead8b9ae62011-11-14 19:07:41 +01001137#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001138
1139/*[clinic input]
1140select.devpoll
1141
1142Returns a polling object.
1143
1144This object supports registering and unregistering file descriptors, and then
1145polling them for I/O events.
1146[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001147
1148static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001149select_devpoll_impl(PyObject *module)
1150/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001151{
1152 return (PyObject *)newDevPollObject();
1153}
1154#endif
1155
1156
Thomas Wouters477c8d52006-05-27 19:21:47 +00001157#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159 * On some systems poll() sets errno on invalid file descriptors. We test
1160 * for this at runtime because this bug may be fixed or introduced between
1161 * OS releases.
1162 */
1163static int select_have_broken_poll(void)
1164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 int poll_test;
1166 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 /* Create a file descriptor to make invalid */
1171 if (pipe(filedes) < 0) {
1172 return 1;
1173 }
1174 poll_struct.fd = filedes[0];
1175 close(filedes[0]);
1176 close(filedes[1]);
1177 poll_test = poll(&poll_struct, 1, 0);
1178 if (poll_test < 0) {
1179 return 1;
1180 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1181 return 1;
1182 }
1183 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184}
1185#endif /* __APPLE__ */
1186
1187#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001188
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001189#ifdef HAVE_EPOLL
1190/* **************************************************************************
1191 * epoll interface for Linux 2.6
1192 *
1193 * Written by Christian Heimes
1194 * Inspired by Twisted's _epoll.pyx and select.poll()
1195 */
1196
1197#ifdef HAVE_SYS_EPOLL_H
1198#include <sys/epoll.h>
1199#endif
1200
1201typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001203 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001204} pyEpoll_Object;
1205
1206static PyTypeObject pyEpoll_Type;
1207#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1208
1209static PyObject *
1210pyepoll_err_closed(void)
1211{
Victor Stinner13423c32013-08-22 00:19:50 +02001212 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001214}
1215
1216static int
1217pyepoll_internal_close(pyEpoll_Object *self)
1218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 int save_errno = 0;
1220 if (self->epfd >= 0) {
1221 int epfd = self->epfd;
1222 self->epfd = -1;
1223 Py_BEGIN_ALLOW_THREADS
1224 if (close(epfd) < 0)
1225 save_errno = errno;
1226 Py_END_ALLOW_THREADS
1227 }
1228 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001229}
1230
1231static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001232newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 assert(type != NULL && type->tp_alloc != NULL);
1237 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1238 if (self == NULL)
1239 return NULL;
1240
1241 if (fd == -1) {
1242 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001243#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001244 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1245#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001246 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001247#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 Py_END_ALLOW_THREADS
1249 }
1250 else {
1251 self->epfd = fd;
1252 }
1253 if (self->epfd < 0) {
1254 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001255 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 return NULL;
1257 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001258
1259#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001260 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001261 Py_DECREF(self);
1262 return NULL;
1263 }
1264#endif
1265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001267}
1268
1269
Tal Einat6dc57e22018-06-30 23:02:48 +03001270/*[clinic input]
1271@classmethod
1272select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001273
Tal Einat6dc57e22018-06-30 23:02:48 +03001274 sizehint: int = -1
1275 The expected number of events to be registered. It must be positive,
1276 or -1 to use the default. It is only used on older systems where
1277 epoll_create1() is not available; otherwise it has no effect (though its
1278 value is still checked).
1279 flags: int = 0
1280 Deprecated and completely ignored. However, when supplied, its value
1281 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1282
1283Returns an epolling object.
1284[clinic start generated code]*/
1285
1286static PyObject *
1287select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1288/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1289{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001290 if (sizehint == -1) {
1291 sizehint = FD_SETSIZE - 1;
1292 }
1293 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001294 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001295 return NULL;
1296 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001297
1298#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001299 if (flags && flags != EPOLL_CLOEXEC) {
1300 PyErr_SetString(PyExc_OSError, "invalid flags");
1301 return NULL;
1302 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001303#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001304
Berker Peksage2197d12016-09-26 23:30:41 +03001305 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001306}
1307
1308
1309static void
1310pyepoll_dealloc(pyEpoll_Object *self)
1311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 (void)pyepoll_internal_close(self);
1313 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001314}
1315
Tal Einat6dc57e22018-06-30 23:02:48 +03001316/*[clinic input]
1317select.epoll.close
1318
1319Close the epoll control file descriptor.
1320
1321Further operations on the epoll object will raise an exception.
1322[clinic start generated code]*/
1323
1324static PyObject *
1325select_epoll_close_impl(pyEpoll_Object *self)
1326/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 errno = pyepoll_internal_close(self);
1329 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001330 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 return NULL;
1332 }
1333 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001334}
1335
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001336
1337static PyObject*
1338pyepoll_get_closed(pyEpoll_Object *self)
1339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if (self->epfd < 0)
1341 Py_RETURN_TRUE;
1342 else
1343 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001344}
1345
Tal Einat6dc57e22018-06-30 23:02:48 +03001346/*[clinic input]
1347select.epoll.fileno
1348
1349Return the epoll control file descriptor.
1350[clinic start generated code]*/
1351
1352static PyObject *
1353select_epoll_fileno_impl(pyEpoll_Object *self)
1354/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 if (self->epfd < 0)
1357 return pyepoll_err_closed();
1358 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359}
1360
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361
Tal Einat6dc57e22018-06-30 23:02:48 +03001362/*[clinic input]
1363@classmethod
1364select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365
Tal Einat6dc57e22018-06-30 23:02:48 +03001366 fd: int
1367 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368
Tal Einat6dc57e22018-06-30 23:02:48 +03001369Create an epoll object from a given control fd.
1370[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001371
1372static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001373select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1374/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1375{
1376 SOCKET s_fd = (SOCKET)fd;
1377 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1378}
1379
1380
1381static PyObject *
1382pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 struct epoll_event ev;
1385 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 if (epfd < 0)
1388 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389
Guido van Rossumee07b942013-12-06 17:46:22 -08001390 switch (op) {
1391 case EPOLL_CTL_ADD:
1392 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 ev.events = events;
1394 ev.data.fd = fd;
1395 Py_BEGIN_ALLOW_THREADS
1396 result = epoll_ctl(epfd, op, fd, &ev);
1397 Py_END_ALLOW_THREADS
1398 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001399 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1401 * operation required a non-NULL pointer in event, even
1402 * though this argument is ignored. */
1403 Py_BEGIN_ALLOW_THREADS
1404 result = epoll_ctl(epfd, op, fd, &ev);
1405 if (errno == EBADF) {
1406 /* fd already closed */
1407 result = 0;
1408 errno = 0;
1409 }
1410 Py_END_ALLOW_THREADS
1411 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001412 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 result = -1;
1414 errno = EINVAL;
1415 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001418 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 return NULL;
1420 }
1421 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422}
1423
Tal Einat6dc57e22018-06-30 23:02:48 +03001424/*[clinic input]
1425select.epoll.register
1426
1427 fd: fildes
1428 the target file descriptor of the operation
1429 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1430 a bit set composed of the various EPOLL constants
1431
1432Registers a new fd or raises an OSError if the fd is already registered.
1433
1434The epoll interface supports all file descriptors that support poll.
1435[clinic start generated code]*/
1436
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001438select_epoll_register_impl(pyEpoll_Object *self, int fd,
1439 unsigned int eventmask)
1440/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441{
Tal Einat6dc57e22018-06-30 23:02:48 +03001442 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001443}
1444
Tal Einat6dc57e22018-06-30 23:02:48 +03001445/*[clinic input]
1446select.epoll.modify
1447
1448 fd: fildes
1449 the target file descriptor of the operation
1450 eventmask: unsigned_int(bitwise=True)
1451 a bit set composed of the various EPOLL constants
1452
1453Modify event mask for a registered file descriptor.
1454[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455
1456static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001457select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1458 unsigned int eventmask)
1459/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001460{
Tal Einat6dc57e22018-06-30 23:02:48 +03001461 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001462}
1463
Tal Einat6dc57e22018-06-30 23:02:48 +03001464/*[clinic input]
1465select.epoll.unregister
1466
1467 fd: fildes
1468 the target file descriptor of the operation
1469
1470Remove a registered file descriptor from the epoll object.
1471[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001472
1473static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001474select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1475/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476{
Tal Einat6dc57e22018-06-30 23:02:48 +03001477 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478}
1479
Tal Einat6dc57e22018-06-30 23:02:48 +03001480/*[clinic input]
1481select.epoll.poll
1482
1483 timeout as timeout_obj: object = None
1484 the maximum time to wait in seconds (as float);
1485 a timeout of None or -1 makes poll wait indefinitely
1486 maxevents: int = -1
1487 the maximum number of events returned; -1 means no limit
1488
1489Wait for events on the epoll file descriptor.
1490
1491Returns a list containing any descriptors that have events to report,
1492as a list of (fd, events) 2-tuples.
1493[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001494
1495static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001496select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1497 int maxevents)
1498/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 int nfds, i;
1501 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001502 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001503 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 if (self->epfd < 0)
1506 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507
Tal Einat6dc57e22018-06-30 23:02:48 +03001508 if (timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001510 ms = -1;
1511 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 }
1513 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001514 /* epoll_wait() has a resolution of 1 millisecond, round towards
1515 infinity to wait at least timeout seconds. */
1516 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001517 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001518 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1519 PyErr_SetString(PyExc_TypeError,
1520 "timeout must be an integer or None");
1521 }
1522 return NULL;
1523 }
1524
1525 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1526 if (ms < INT_MIN || ms > INT_MAX) {
1527 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1528 return NULL;
1529 }
1530
1531 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001535 maxevents = FD_SETSIZE-1;
1536 }
1537 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyErr_Format(PyExc_ValueError,
1539 "maxevents must be greater than 0, got %d",
1540 maxevents);
1541 return NULL;
1542 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001543
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001544 evs = PyMem_New(struct epoll_event, maxevents);
1545 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001546 PyErr_NoMemory();
1547 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001549
Victor Stinner41eba222015-03-30 21:59:21 +02001550 do {
1551 Py_BEGIN_ALLOW_THREADS
1552 errno = 0;
1553 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1554 Py_END_ALLOW_THREADS
1555
1556 if (errno != EINTR)
1557 break;
1558
1559 /* poll() was interrupted by a signal */
1560 if (PyErr_CheckSignals())
1561 goto error;
1562
1563 if (timeout >= 0) {
1564 timeout = deadline - _PyTime_GetMonotonicClock();
1565 if (timeout < 0) {
1566 nfds = 0;
1567 break;
1568 }
1569 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1570 /* retry epoll_wait() with the recomputed timeout */
1571 }
1572 } while(1);
1573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001575 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 goto error;
1577 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 elist = PyList_New(nfds);
1580 if (elist == NULL) {
1581 goto error;
1582 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001585 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 if (etuple == NULL) {
1587 Py_CLEAR(elist);
1588 goto error;
1589 }
1590 PyList_SET_ITEM(elist, i, etuple);
1591 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Christian Heimesf6cd9672008-03-26 13:45:42 +00001593 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001594 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596}
1597
Tal Einat6dc57e22018-06-30 23:02:48 +03001598
1599/*[clinic input]
1600select.epoll.__enter__
1601
1602[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001603
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001604static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001605select_epoll___enter___impl(pyEpoll_Object *self)
1606/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001607{
1608 if (self->epfd < 0)
1609 return pyepoll_err_closed();
1610
1611 Py_INCREF(self);
1612 return (PyObject *)self;
1613}
1614
Tal Einat6dc57e22018-06-30 23:02:48 +03001615/*[clinic input]
1616select.epoll.__exit__
1617
1618 exc_type: object = None
1619 exc_value: object = None
1620 exc_tb: object = None
1621 /
1622
1623[clinic start generated code]*/
1624
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001625static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001626select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1627 PyObject *exc_value, PyObject *exc_tb)
1628/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001629{
1630 _Py_IDENTIFIER(close);
1631
Tal Einat6dc57e22018-06-30 23:02:48 +03001632 return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001633}
1634
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001635static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 {"closed", (getter)pyepoll_get_closed, NULL,
1637 "True if the epoll handler is closed"},
1638 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001639};
1640
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001641#endif /* HAVE_EPOLL */
1642
1643#ifdef HAVE_KQUEUE
1644/* **************************************************************************
1645 * kqueue interface for BSD
1646 *
1647 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1648 * All rights reserved.
1649 *
1650 * Redistribution and use in source and binary forms, with or without
1651 * modification, are permitted provided that the following conditions
1652 * are met:
1653 * 1. Redistributions of source code must retain the above copyright
1654 * notice, this list of conditions and the following disclaimer.
1655 * 2. Redistributions in binary form must reproduce the above copyright
1656 * notice, this list of conditions and the following disclaimer in the
1657 * documentation and/or other materials provided with the distribution.
1658 *
1659 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1660 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1661 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1662 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1663 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1664 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1665 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1666 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1667 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1668 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1669 * SUCH DAMAGE.
1670 */
1671
1672#ifdef HAVE_SYS_EVENT_H
1673#include <sys/event.h>
1674#endif
1675
1676PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001677"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001678\n\
1679This object is the equivalent of the struct kevent for the C API.\n\
1680\n\
1681See the kqueue manpage for more detailed information about the meaning\n\
1682of the arguments.\n\
1683\n\
1684One minor note: while you might hope that udata could store a\n\
1685reference to a python object, it cannot, because it is impossible to\n\
1686keep a proper reference count of the object once it's passed into the\n\
1687kernel. Therefore, I have restricted it to only storing an integer. I\n\
1688recommend ignoring it and simply using the 'ident' field to key off\n\
1689of. You could also set up a dictionary on the python side to store a\n\
1690udata->object mapping.");
1691
1692typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 PyObject_HEAD
1694 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001695} kqueue_event_Object;
1696
1697static PyTypeObject kqueue_event_Type;
1698
1699#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1700
1701typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 PyObject_HEAD
1703 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001704} kqueue_queue_Object;
1705
1706static PyTypeObject kqueue_queue_Type;
1707
1708#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1709
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001710#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1711# error uintptr_t does not match void *!
1712#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1713# define T_UINTPTRT T_ULONGLONG
1714# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001715# define UINTPTRT_FMT_UNIT "K"
1716# define INTPTRT_FMT_UNIT "L"
1717#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1718# define T_UINTPTRT T_ULONG
1719# define T_INTPTRT T_LONG
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_INT)
1723# define T_UINTPTRT T_UINT
1724# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001725# define UINTPTRT_FMT_UNIT "I"
1726# define INTPTRT_FMT_UNIT "i"
1727#else
1728# error uintptr_t does not match int, long, or long long!
1729#endif
1730
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001731#if SIZEOF_LONG_LONG == 8
1732# define T_INT64 T_LONGLONG
1733# define INT64_FMT_UNIT "L"
1734#elif SIZEOF_LONG == 8
1735# define T_INT64 T_LONG
1736# define INT64_FMT_UNIT "l"
1737#elif SIZEOF_INT == 8
1738# define T_INT64 T_INT
1739# define INT64_FMT_UNIT "i"
1740#else
1741# define INT64_FMT_UNIT "_"
1742#endif
1743
1744#if SIZEOF_LONG_LONG == 4
1745# define T_UINT32 T_ULONGLONG
1746# define UINT32_FMT_UNIT "K"
1747#elif SIZEOF_LONG == 4
1748# define T_UINT32 T_ULONG
1749# define UINT32_FMT_UNIT "k"
1750#elif SIZEOF_INT == 4
1751# define T_UINT32 T_UINT
1752# define UINT32_FMT_UNIT "I"
1753#else
1754# define UINT32_FMT_UNIT "_"
1755#endif
1756
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001757/*
1758 * kevent is not standard and its members vary across BSDs.
1759 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001760#ifdef __NetBSD__
1761# define FILTER_TYPE T_UINT32
1762# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1763# define FLAGS_TYPE T_UINT32
1764# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1765# define FFLAGS_TYPE T_UINT32
1766# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001767#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001768# define FILTER_TYPE T_SHORT
1769# define FILTER_FMT_UNIT "h"
1770# define FLAGS_TYPE T_USHORT
1771# define FLAGS_FMT_UNIT "H"
1772# define FFLAGS_TYPE T_UINT
1773# define FFLAGS_FMT_UNIT "I"
1774#endif
1775
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001776#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001777# define DATA_TYPE T_INT64
1778# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001779#else
1780# define DATA_TYPE T_INTPTRT
1781# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001782#endif
1783
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001784/* Unfortunately, we can't store python objects in udata, because
1785 * kevents in the kernel can be removed without warning, which would
1786 * forever lose the refcount on the object stored with it.
1787 */
1788
1789#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1790static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001791 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1792 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1793 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001795 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1797 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001798};
1799#undef KQ_OFF
1800
1801static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001802
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001803kqueue_event_repr(kqueue_event_Object *s)
1804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 char buf[1024];
1806 PyOS_snprintf(
1807 buf, sizeof(buf),
1808 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001809 "data=0x%llx udata=%p>",
1810 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1811 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001813}
1814
1815static int
1816kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 PyObject *pfd;
1819 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1820 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001821 static const char fmt[] = "O|"
1822 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1823 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1828 &pfd, &(self->e.filter), &(self->e.flags),
1829 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1830 return -1;
1831 }
1832
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001833 if (PyLong_Check(pfd)) {
1834 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 }
1836 else {
1837 self->e.ident = PyObject_AsFileDescriptor(pfd);
1838 }
1839 if (PyErr_Occurred()) {
1840 return -1;
1841 }
1842 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001843}
1844
1845static PyObject *
1846kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001848{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001849 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001852 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001854
1855#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1856 result = CMP(s->e.ident, o->e.ident)
1857 : CMP(s->e.filter, o->e.filter)
1858 : CMP(s->e.flags, o->e.flags)
1859 : CMP(s->e.fflags, o->e.fflags)
1860 : CMP(s->e.data, o->e.data)
1861 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1862 : 0;
1863#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001864
stratakise8b19652017-11-02 11:32:54 +01001865 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001866}
1867
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868static PyObject *
1869kqueue_queue_err_closed(void)
1870{
Victor Stinner13423c32013-08-22 00:19:50 +02001871 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873}
1874
1875static int
1876kqueue_queue_internal_close(kqueue_queue_Object *self)
1877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 int save_errno = 0;
1879 if (self->kqfd >= 0) {
1880 int kqfd = self->kqfd;
1881 self->kqfd = -1;
1882 Py_BEGIN_ALLOW_THREADS
1883 if (close(kqfd) < 0)
1884 save_errno = errno;
1885 Py_END_ALLOW_THREADS
1886 }
1887 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001888}
1889
1890static PyObject *
1891newKqueue_Object(PyTypeObject *type, SOCKET fd)
1892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 kqueue_queue_Object *self;
1894 assert(type != NULL && type->tp_alloc != NULL);
1895 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1896 if (self == NULL) {
1897 return NULL;
1898 }
1899
1900 if (fd == -1) {
1901 Py_BEGIN_ALLOW_THREADS
1902 self->kqfd = kqueue();
1903 Py_END_ALLOW_THREADS
1904 }
1905 else {
1906 self->kqfd = fd;
1907 }
1908 if (self->kqfd < 0) {
1909 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001910 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 return NULL;
1912 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001913
1914 if (fd == -1) {
1915 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1916 Py_DECREF(self);
1917 return NULL;
1918 }
1919 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921}
1922
Tal Einat6dc57e22018-06-30 23:02:48 +03001923/*[clinic input]
1924@classmethod
1925select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001926
Tal Einat6dc57e22018-06-30 23:02:48 +03001927Kqueue syscall wrapper.
1928
1929For example, to start watching a socket for input:
1930>>> kq = kqueue()
1931>>> sock = socket()
1932>>> sock.connect((host, port))
1933>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1934
1935To wait one second for it to become writeable:
1936>>> kq.control(None, 1, 1000)
1937
1938To stop listening:
1939>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1940[clinic start generated code]*/
1941
1942static PyObject *
1943select_kqueue_impl(PyTypeObject *type)
1944/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001947}
1948
1949static void
1950kqueue_queue_dealloc(kqueue_queue_Object *self)
1951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 kqueue_queue_internal_close(self);
1953 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001954}
1955
Tal Einat6dc57e22018-06-30 23:02:48 +03001956/*[clinic input]
1957select.kqueue.close
1958
1959Close the kqueue control file descriptor.
1960
1961Further operations on the kqueue object will raise an exception.
1962[clinic start generated code]*/
1963
1964static PyObject *
1965select_kqueue_close_impl(kqueue_queue_Object *self)
1966/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 errno = kqueue_queue_internal_close(self);
1969 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001970 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 return NULL;
1972 }
1973 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001974}
1975
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001976static PyObject*
1977kqueue_queue_get_closed(kqueue_queue_Object *self)
1978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 if (self->kqfd < 0)
1980 Py_RETURN_TRUE;
1981 else
1982 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001983}
1984
Tal Einat6dc57e22018-06-30 23:02:48 +03001985/*[clinic input]
1986select.kqueue.fileno
1987
1988Return the kqueue control file descriptor.
1989[clinic start generated code]*/
1990
1991static PyObject *
1992select_kqueue_fileno_impl(kqueue_queue_Object *self)
1993/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 if (self->kqfd < 0)
1996 return kqueue_queue_err_closed();
1997 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001998}
1999
Tal Einat6dc57e22018-06-30 23:02:48 +03002000/*[clinic input]
2001@classmethod
2002select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003
Tal Einat6dc57e22018-06-30 23:02:48 +03002004 fd: int
2005 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002006
Tal Einat6dc57e22018-06-30 23:02:48 +03002007Create a kqueue object from a given control fd.
2008[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002009
2010static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002011select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2012/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002013{
Tal Einat6dc57e22018-06-30 23:02:48 +03002014 SOCKET s_fd = (SOCKET)fd;
2015
2016 return newKqueue_Object(type, s_fd);
2017}
2018
2019/*[clinic input]
2020select.kqueue.control
2021
2022 changelist: object
2023 Must be an iterable of kevent objects describing the changes to be made
2024 to the kernel's watch list or None.
2025 maxevents: int
2026 The maximum number of events that the kernel will return.
2027 timeout as otimeout: object = None
2028 The maximum time to wait in seconds, or else None to wait forever.
2029 This accepts floats for smaller timeouts, too.
2030 /
2031
2032Calls the kernel kevent function.
2033[clinic start generated code]*/
2034
2035static PyObject *
2036select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2037 int maxevents, PyObject *otimeout)
2038/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 int gotevents = 0;
2041 int nchanges = 0;
2042 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002043 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 PyObject *result = NULL;
2045 struct kevent *evl = NULL;
2046 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002047 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002049 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 if (self->kqfd < 0)
2052 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002053
Tal Einat6dc57e22018-06-30 23:02:48 +03002054 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 PyErr_Format(PyExc_ValueError,
2056 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002057 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 return NULL;
2059 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002060
Tal Einat6dc57e22018-06-30 23:02:48 +03002061 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 ptimeoutspec = NULL;
2063 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002064 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002065 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002066 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002067 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002068 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002069 "or None, got %.200s",
2070 Py_TYPE(otimeout)->tp_name);
2071 return NULL;
2072 }
2073
Victor Stinner4448c082015-03-31 11:48:34 +02002074 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002075 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076
Victor Stinner4448c082015-03-31 11:48:34 +02002077 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 PyErr_SetString(PyExc_ValueError,
2079 "timeout must be positive or None");
2080 return NULL;
2081 }
Victor Stinner4448c082015-03-31 11:48:34 +02002082 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002084
Tal Einat6dc57e22018-06-30 23:02:48 +03002085 if (changelist != Py_None) {
2086 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002087 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 return NULL;
2089 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002090 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2091 PyErr_SetString(PyExc_OverflowError,
2092 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 goto error;
2094 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002095 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 chl = PyMem_New(struct kevent, nchanges);
2098 if (chl == NULL) {
2099 PyErr_NoMemory();
2100 goto error;
2101 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002102 for (i = 0; i < nchanges; ++i) {
2103 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 PyErr_SetString(PyExc_TypeError,
2106 "changelist must be an iterable of "
2107 "select.kevent objects");
2108 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002110 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002112 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002116 if (maxevents) {
2117 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 if (evl == NULL) {
2119 PyErr_NoMemory();
2120 goto error;
2121 }
2122 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002123
Victor Stinner4448c082015-03-31 11:48:34 +02002124 if (ptimeoutspec)
2125 deadline = _PyTime_GetMonotonicClock() + timeout;
2126
2127 do {
2128 Py_BEGIN_ALLOW_THREADS
2129 errno = 0;
2130 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002131 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002132 Py_END_ALLOW_THREADS
2133
2134 if (errno != EINTR)
2135 break;
2136
2137 /* kevent() was interrupted by a signal */
2138 if (PyErr_CheckSignals())
2139 goto error;
2140
2141 if (ptimeoutspec) {
2142 timeout = deadline - _PyTime_GetMonotonicClock();
2143 if (timeout < 0) {
2144 gotevents = 0;
2145 break;
2146 }
2147 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2148 goto error;
2149 /* retry kevent() with the recomputed timeout */
2150 }
2151 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 if (gotevents == -1) {
2154 PyErr_SetFromErrno(PyExc_OSError);
2155 goto error;
2156 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 result = PyList_New(gotevents);
2159 if (result == NULL) {
2160 goto error;
2161 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 for (i = 0; i < gotevents; i++) {
2164 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2167 if (ch == NULL) {
2168 goto error;
2169 }
2170 ch->e = evl[i];
2171 PyList_SET_ITEM(result, i, (PyObject *)ch);
2172 }
2173 PyMem_Free(chl);
2174 PyMem_Free(evl);
2175 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002176
2177 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 PyMem_Free(chl);
2179 PyMem_Free(evl);
2180 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002181 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002183}
2184
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002185static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 {"closed", (getter)kqueue_queue_get_closed, NULL,
2187 "True if the kqueue handler is closed"},
2188 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002189};
2190
Tal Einat6dc57e22018-06-30 23:02:48 +03002191#endif /* HAVE_KQUEUE */
2192
2193
2194/* ************************************************************************ */
2195
2196#include "clinic/selectmodule.c.h"
2197
2198#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2199
2200static PyMethodDef poll_methods[] = {
2201 SELECT_POLL_REGISTER_METHODDEF
2202 SELECT_POLL_MODIFY_METHODDEF
2203 SELECT_POLL_UNREGISTER_METHODDEF
2204 SELECT_POLL_POLL_METHODDEF
2205 {NULL, NULL} /* sentinel */
2206};
2207
2208static PyTypeObject poll_Type = {
2209 /* The ob_type field must be initialized in the module init function
2210 * to be portable to Windows without using C++. */
2211 PyVarObject_HEAD_INIT(NULL, 0)
2212 "select.poll", /*tp_name*/
2213 sizeof(pollObject), /*tp_basicsize*/
2214 0, /*tp_itemsize*/
2215 /* methods */
2216 (destructor)poll_dealloc, /*tp_dealloc*/
2217 0, /*tp_print*/
2218 0, /*tp_getattr*/
2219 0, /*tp_setattr*/
2220 0, /*tp_reserved*/
2221 0, /*tp_repr*/
2222 0, /*tp_as_number*/
2223 0, /*tp_as_sequence*/
2224 0, /*tp_as_mapping*/
2225 0, /*tp_hash*/
2226 0, /*tp_call*/
2227 0, /*tp_str*/
2228 0, /*tp_getattro*/
2229 0, /*tp_setattro*/
2230 0, /*tp_as_buffer*/
2231 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2232 0, /*tp_doc*/
2233 0, /*tp_traverse*/
2234 0, /*tp_clear*/
2235 0, /*tp_richcompare*/
2236 0, /*tp_weaklistoffset*/
2237 0, /*tp_iter*/
2238 0, /*tp_iternext*/
2239 poll_methods, /*tp_methods*/
2240};
2241
2242#ifdef HAVE_SYS_DEVPOLL_H
2243
2244static PyMethodDef devpoll_methods[] = {
2245 SELECT_DEVPOLL_REGISTER_METHODDEF
2246 SELECT_DEVPOLL_MODIFY_METHODDEF
2247 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2248 SELECT_DEVPOLL_POLL_METHODDEF
2249 SELECT_DEVPOLL_CLOSE_METHODDEF
2250 SELECT_DEVPOLL_FILENO_METHODDEF
2251 {NULL, NULL} /* sentinel */
2252};
2253
2254static PyTypeObject devpoll_Type = {
2255 /* The ob_type field must be initialized in the module init function
2256 * to be portable to Windows without using C++. */
2257 PyVarObject_HEAD_INIT(NULL, 0)
2258 "select.devpoll", /*tp_name*/
2259 sizeof(devpollObject), /*tp_basicsize*/
2260 0, /*tp_itemsize*/
2261 /* methods */
2262 (destructor)devpoll_dealloc, /*tp_dealloc*/
2263 0, /*tp_print*/
2264 0, /*tp_getattr*/
2265 0, /*tp_setattr*/
2266 0, /*tp_reserved*/
2267 0, /*tp_repr*/
2268 0, /*tp_as_number*/
2269 0, /*tp_as_sequence*/
2270 0, /*tp_as_mapping*/
2271 0, /*tp_hash*/
2272 0, /*tp_call*/
2273 0, /*tp_str*/
2274 0, /*tp_getattro*/
2275 0, /*tp_setattro*/
2276 0, /*tp_as_buffer*/
2277 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2278 0, /*tp_doc*/
2279 0, /*tp_traverse*/
2280 0, /*tp_clear*/
2281 0, /*tp_richcompare*/
2282 0, /*tp_weaklistoffset*/
2283 0, /*tp_iter*/
2284 0, /*tp_iternext*/
2285 devpoll_methods, /*tp_methods*/
2286 0, /* tp_members */
2287 devpoll_getsetlist, /* tp_getset */
2288};
2289
2290#endif /* HAVE_SYS_DEVPOLL_H */
2291
2292#endif /* HAVE_POLL */
2293
2294#ifdef HAVE_EPOLL
2295
2296static PyMethodDef pyepoll_methods[] = {
2297 SELECT_EPOLL_FROMFD_METHODDEF
2298 SELECT_EPOLL_CLOSE_METHODDEF
2299 SELECT_EPOLL_FILENO_METHODDEF
2300 SELECT_EPOLL_MODIFY_METHODDEF
2301 SELECT_EPOLL_REGISTER_METHODDEF
2302 SELECT_EPOLL_UNREGISTER_METHODDEF
2303 SELECT_EPOLL_POLL_METHODDEF
2304 SELECT_EPOLL___ENTER___METHODDEF
2305 SELECT_EPOLL___EXIT___METHODDEF
2306 {NULL, NULL},
2307};
2308
2309static PyTypeObject pyEpoll_Type = {
2310 PyVarObject_HEAD_INIT(NULL, 0)
2311 "select.epoll", /* tp_name */
2312 sizeof(pyEpoll_Object), /* tp_basicsize */
2313 0, /* tp_itemsize */
2314 (destructor)pyepoll_dealloc, /* tp_dealloc */
2315 0, /* tp_print */
2316 0, /* tp_getattr */
2317 0, /* tp_setattr */
2318 0, /* tp_reserved */
2319 0, /* tp_repr */
2320 0, /* tp_as_number */
2321 0, /* tp_as_sequence */
2322 0, /* tp_as_mapping */
2323 0, /* tp_hash */
2324 0, /* tp_call */
2325 0, /* tp_str */
2326 PyObject_GenericGetAttr, /* tp_getattro */
2327 0, /* tp_setattro */
2328 0, /* tp_as_buffer */
2329 Py_TPFLAGS_DEFAULT, /* tp_flags */
2330 select_epoll__doc__, /* tp_doc */
2331 0, /* tp_traverse */
2332 0, /* tp_clear */
2333 0, /* tp_richcompare */
2334 0, /* tp_weaklistoffset */
2335 0, /* tp_iter */
2336 0, /* tp_iternext */
2337 pyepoll_methods, /* tp_methods */
2338 0, /* tp_members */
2339 pyepoll_getsetlist, /* tp_getset */
2340 0, /* tp_base */
2341 0, /* tp_dict */
2342 0, /* tp_descr_get */
2343 0, /* tp_descr_set */
2344 0, /* tp_dictoffset */
2345 0, /* tp_init */
2346 0, /* tp_alloc */
2347 select_epoll, /* tp_new */
2348 0, /* tp_free */
2349};
2350
2351#endif /* HAVE_EPOLL */
2352
2353#ifdef HAVE_KQUEUE
2354
2355static PyTypeObject kqueue_event_Type = {
2356 PyVarObject_HEAD_INIT(NULL, 0)
2357 "select.kevent", /* tp_name */
2358 sizeof(kqueue_event_Object), /* tp_basicsize */
2359 0, /* tp_itemsize */
2360 0, /* tp_dealloc */
2361 0, /* tp_print */
2362 0, /* tp_getattr */
2363 0, /* tp_setattr */
2364 0, /* tp_reserved */
2365 (reprfunc)kqueue_event_repr, /* tp_repr */
2366 0, /* tp_as_number */
2367 0, /* tp_as_sequence */
2368 0, /* tp_as_mapping */
2369 0, /* tp_hash */
2370 0, /* tp_call */
2371 0, /* tp_str */
2372 0, /* tp_getattro */
2373 0, /* tp_setattro */
2374 0, /* tp_as_buffer */
2375 Py_TPFLAGS_DEFAULT, /* tp_flags */
2376 kqueue_event_doc, /* tp_doc */
2377 0, /* tp_traverse */
2378 0, /* tp_clear */
2379 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
2380 0, /* tp_weaklistoffset */
2381 0, /* tp_iter */
2382 0, /* tp_iternext */
2383 0, /* tp_methods */
2384 kqueue_event_members, /* tp_members */
2385 0, /* tp_getset */
2386 0, /* tp_base */
2387 0, /* tp_dict */
2388 0, /* tp_descr_get */
2389 0, /* tp_descr_set */
2390 0, /* tp_dictoffset */
2391 (initproc)kqueue_event_init, /* tp_init */
2392 0, /* tp_alloc */
2393 0, /* tp_new */
2394 0, /* tp_free */
2395};
2396
2397static PyMethodDef kqueue_queue_methods[] = {
2398 SELECT_KQUEUE_FROMFD_METHODDEF
2399 SELECT_KQUEUE_CLOSE_METHODDEF
2400 SELECT_KQUEUE_FILENO_METHODDEF
2401 SELECT_KQUEUE_CONTROL_METHODDEF
2402 {NULL, NULL},
2403};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002404
2405static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 PyVarObject_HEAD_INIT(NULL, 0)
2407 "select.kqueue", /* tp_name */
2408 sizeof(kqueue_queue_Object), /* tp_basicsize */
2409 0, /* tp_itemsize */
2410 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2411 0, /* tp_print */
2412 0, /* tp_getattr */
2413 0, /* tp_setattr */
2414 0, /* tp_reserved */
2415 0, /* tp_repr */
2416 0, /* tp_as_number */
2417 0, /* tp_as_sequence */
2418 0, /* tp_as_mapping */
2419 0, /* tp_hash */
2420 0, /* tp_call */
2421 0, /* tp_str */
2422 0, /* tp_getattro */
2423 0, /* tp_setattro */
2424 0, /* tp_as_buffer */
2425 Py_TPFLAGS_DEFAULT, /* tp_flags */
Tal Einat6dc57e22018-06-30 23:02:48 +03002426 select_kqueue__doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 0, /* tp_traverse */
2428 0, /* tp_clear */
2429 0, /* tp_richcompare */
2430 0, /* tp_weaklistoffset */
2431 0, /* tp_iter */
2432 0, /* tp_iternext */
2433 kqueue_queue_methods, /* tp_methods */
2434 0, /* tp_members */
2435 kqueue_queue_getsetlist, /* tp_getset */
2436 0, /* tp_base */
2437 0, /* tp_dict */
2438 0, /* tp_descr_get */
2439 0, /* tp_descr_set */
2440 0, /* tp_dictoffset */
2441 0, /* tp_init */
2442 0, /* tp_alloc */
Tal Einat6dc57e22018-06-30 23:02:48 +03002443 select_kqueue, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002445};
2446
2447#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002448
2449
2450
2451
2452
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002453/* ************************************************************************ */
2454
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002455
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002456static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002457 SELECT_SELECT_METHODDEF
2458 SELECT_POLL_METHODDEF
2459 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002461};
2462
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002464"This module supports asynchronous I/O on multiple file descriptors.\n\
2465\n\
2466*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002467On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002468
Martin v. Löwis1a214512008-06-11 05:26:20 +00002469
2470static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 PyModuleDef_HEAD_INIT,
2472 "select",
2473 module_doc,
2474 -1,
2475 select_methods,
2476 NULL,
2477 NULL,
2478 NULL,
2479 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002480};
2481
Jesus Cead8b9ae62011-11-14 19:07:41 +01002482
2483
2484
Mark Hammond62b1ab12002-07-23 06:31:15 +00002485PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002486PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 PyObject *m;
2489 m = PyModule_Create(&selectmodule);
2490 if (m == NULL)
2491 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002492
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002493 Py_INCREF(PyExc_OSError);
2494 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002495
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002496#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002497#ifdef HAVE_BROKEN_PIPE_BUF
2498#undef PIPE_BUF
2499#define PIPE_BUF 512
2500#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002501 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002502#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002503
Charles-François Natali986a56c2013-01-19 12:19:10 +01002504#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002505#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 if (select_have_broken_poll()) {
2507 if (PyObject_DelAttrString(m, "poll") == -1) {
2508 PyErr_Clear();
2509 }
2510 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002511#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002513#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 if (PyType_Ready(&poll_Type) < 0)
2515 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002516 PyModule_AddIntMacro(m, POLLIN);
2517 PyModule_AddIntMacro(m, POLLPRI);
2518 PyModule_AddIntMacro(m, POLLOUT);
2519 PyModule_AddIntMacro(m, POLLERR);
2520 PyModule_AddIntMacro(m, POLLHUP);
2521 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002522
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002523#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002524 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002525#endif
2526#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002527 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002528#endif
2529#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002530 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002531#endif
2532#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002533 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002534#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002535#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002536 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002537#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002538#ifdef POLLRDHUP
2539 /* Kernel 2.6.17+ */
2540 PyModule_AddIntMacro(m, POLLRDHUP);
2541#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002543#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002544
Jesus Cead8b9ae62011-11-14 19:07:41 +01002545#ifdef HAVE_SYS_DEVPOLL_H
2546 if (PyType_Ready(&devpoll_Type) < 0)
2547 return NULL;
2548#endif
2549
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002550#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2552 if (PyType_Ready(&pyEpoll_Type) < 0)
2553 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 Py_INCREF(&pyEpoll_Type);
2556 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002557
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002558 PyModule_AddIntMacro(m, EPOLLIN);
2559 PyModule_AddIntMacro(m, EPOLLOUT);
2560 PyModule_AddIntMacro(m, EPOLLPRI);
2561 PyModule_AddIntMacro(m, EPOLLERR);
2562 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002563#ifdef EPOLLRDHUP
2564 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002565 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002566#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002567 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002568#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002570 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002571#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002572#ifdef EPOLLEXCLUSIVE
2573 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2574#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002575
2576#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002577 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002578#endif
2579#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002580 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002581#endif
2582#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002583 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002584#endif
2585#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002586 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002587#endif
2588#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002589 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002590#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002591
Benjamin Peterson95c16622011-12-27 15:36:32 -06002592#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002593 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002594#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002595#endif /* HAVE_EPOLL */
2596
2597#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 kqueue_event_Type.tp_new = PyType_GenericNew;
2599 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2600 if(PyType_Ready(&kqueue_event_Type) < 0)
2601 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002603 Py_INCREF(&kqueue_event_Type);
2604 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2607 if(PyType_Ready(&kqueue_queue_Type) < 0)
2608 return NULL;
2609 Py_INCREF(&kqueue_queue_Type);
2610 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2611
2612 /* event filters */
2613 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2614 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002615#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002617#endif
2618#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#endif
2621#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002623#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002624#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002626#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002627#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002629#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 /* event flags */
2633 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2634 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2635 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2636 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2637 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2638 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002639
Berker Peksag7ec64562016-09-14 18:16:59 +03002640#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002642#endif
2643#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002645#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2648 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002651#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002653#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002656#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2658 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2659 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2660 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2661 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2662 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2663 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002664#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002666 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002667#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2669 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2670 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2671 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2672 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002674 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2675 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2676 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002677#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678
2679 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002680#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002681 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2682 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2683 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002684#endif
2685
2686#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002688}