blob: 5c15e9973ab84d6c9c40201c935fcbc11db4a084 [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"
Victor Stinner4a21e572020-04-15 02:35:41 +020012#include "structmember.h" // PyMemberDef
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
Dino Viehlandf9190542019-09-14 15:20:27 +010061typedef struct {
62 PyObject *close;
63 PyTypeObject *poll_Type;
64 PyTypeObject *devpoll_Type;
65 PyTypeObject *pyEpoll_Type;
66 PyTypeObject *kqueue_event_Type;
67 PyTypeObject *kqueue_queue_Type;
68} _selectstate;
69
70static struct PyModuleDef selectmodule;
71
Hai Shif707d942020-03-16 21:15:01 +080072static inline _selectstate*
73get_select_state(PyObject *module)
74{
75 void *state = PyModule_GetState(module);
76 assert(state != NULL);
77 return (_selectstate *)state;
78}
79
80#define _selectstate_global get_select_state(PyState_FindModule(&selectmodule))
Dino Viehlandf9190542019-09-14 15:20:27 +010081
Tal Einat6dc57e22018-06-30 23:02:48 +030082/*[clinic input]
83module select
84class select.poll "pollObject *" "&poll_Type"
85class select.devpoll "devpollObject *" "&devpoll_Type"
86class select.epoll "pyEpoll_Object *" "&pyEpoll_Type"
Dino Viehlandf9190542019-09-14 15:20:27 +010087class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_Type"
Tal Einat6dc57e22018-06-30 23:02:48 +030088[clinic start generated code]*/
Dino Viehlandf9190542019-09-14 15:20:27 +010089/*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/
Tal Einat6dc57e22018-06-30 23:02:48 +030090
91static int
92fildes_converter(PyObject *o, void *p)
93{
94 int fd;
95 int *pointer = (int *)p;
96 fd = PyObject_AsFileDescriptor(o);
97 if (fd == -1)
98 return 0;
99 *pointer = fd;
100 return 1;
101}
102
103/*[python input]
104class fildes_converter(CConverter):
105 type = 'int'
106 converter = 'fildes_converter'
107[python start generated code]*/
108/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/
109
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110/* list of Python objects and their file descriptor */
111typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 PyObject *obj; /* owned reference */
113 SOCKET fd;
114 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000115} pylist;
116
Barry Warsawc1cb3601996-12-12 22:16:21 +0000117static void
Tim Peters4b046c22001-08-16 21:59:46 +0000118reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200120 unsigned int i;
121 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200122 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 }
124 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000125}
126
127
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000128/* returns -1 and sets the Python exception if an error occurred, otherwise
129 returns a number >= 0
130*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000131static int
Brett Cannon62dba4c2003-09-10 19:37:42 +0000132seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200135 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100136 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 PyObject* fast_seq = NULL;
138 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +0000139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
141 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142
Benjamin Petersone0edb8b2010-06-27 23:49:45 +0000143 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 if (!fast_seq)
145 return -1;
146
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100147 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 SOCKET v;
149
150 /* any intervening fileno() calls could decr this refcnt */
151 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200152 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 Py_INCREF(o);
155 v = PyObject_AsFileDescriptor( o );
156 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000157
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000158#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000160#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200161 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 PyErr_SetString(PyExc_ValueError,
163 "filedescriptor out of range in select()");
164 goto finally;
165 }
166 if (v > max)
167 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200172 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 PyErr_SetString(PyExc_ValueError,
174 "too many file descriptors in select()");
175 goto finally;
176 }
177 fd2obj[index].obj = o;
178 fd2obj[index].fd = v;
179 fd2obj[index].sentinel = 0;
180 fd2obj[++index].sentinel = -1;
181 }
182 Py_DECREF(fast_seq);
183 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000184
185 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 Py_XDECREF(o);
187 Py_DECREF(fast_seq);
188 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000189}
190
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000191/* returns NULL and sets the Python exception if an error occurred */
192static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000193set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 int i, j, count=0;
196 PyObject *list, *o;
197 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
200 if (FD_ISSET(fd2obj[j].fd, set))
201 count++;
202 }
203 list = PyList_New(count);
204 if (!list)
205 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 i = 0;
208 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
209 fd = fd2obj[j].fd;
210 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 o = fd2obj[j].obj;
212 fd2obj[j].obj = NULL;
213 /* transfer ownership */
214 if (PyList_SetItem(list, i, o) < 0)
215 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 i++;
218 }
219 }
220 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000221 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 Py_DECREF(list);
223 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000224}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000225
Barry Warsawb44740f2001-08-16 16:52:59 +0000226#undef SELECT_USES_HEAP
227#if FD_SETSIZE > 1024
228#define SELECT_USES_HEAP
229#endif /* FD_SETSIZE > 1024 */
230
Tal Einat6dc57e22018-06-30 23:02:48 +0300231/*[clinic input]
232select.select
233
234 rlist: object
235 wlist: object
236 xlist: object
237 timeout as timeout_obj: object = None
238 /
239
240Wait until one or more file descriptors are ready for some kind of I/O.
241
242The first three arguments are sequences of file descriptors to be waited for:
243rlist -- wait until ready for reading
244wlist -- wait until ready for writing
245xlist -- wait for an "exceptional condition"
246If only one kind of condition is required, pass [] for the other lists.
247
248A file descriptor is either a socket or file object, or a small integer
249gotten from a fileno() method call on one of those.
250
251The optional 4th argument specifies a timeout in seconds; it may be
252a floating point number to specify fractions of seconds. If it is absent
253or None, the call will never time out.
254
255The return value is a tuple of three lists corresponding to the first three
256arguments; each contains the subset of the corresponding file descriptors
257that are ready.
258
259*** IMPORTANT NOTICE ***
260On Windows, only sockets are supported; on Unix, all file
261descriptors can be used.
262[clinic start generated code]*/
263
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000264static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300265select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
266 PyObject *xlist, PyObject *timeout_obj)
267/*[clinic end generated code: output=2b3cfa824f7ae4cf input=177e72184352df25]*/
Guido van Rossumed233a51992-06-23 09:07:03 +0000268{
Barry Warsawb44740f2001-08-16 16:52:59 +0000269#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000271#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 /* XXX: All this should probably be implemented as follows:
273 * - find the highest descriptor we're interested in
274 * - add one
275 * - that's the size
276 * See: Stevens, APitUE, $12.5.1
277 */
278 pylist rfd2obj[FD_SETSIZE + 1];
279 pylist wfd2obj[FD_SETSIZE + 1];
280 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000281#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 PyObject *ret = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 int imax, omax, emax, max;
286 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200287 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000288
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200289 if (timeout_obj == Py_None)
290 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200292 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100293 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200294 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
295 PyErr_SetString(PyExc_TypeError,
296 "timeout must be a float or None");
297 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100298 return NULL;
299 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100300
Pablo Galindo2c15b292017-10-17 15:14:41 +0100301 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100302 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100303 if (tv.tv_sec < 0) {
304 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 return NULL;
306 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 tvp = &tv;
308 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000309
Barry Warsawb44740f2001-08-16 16:52:59 +0000310#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 /* Allocate memory for the lists */
312 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
313 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
314 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
315 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
316 if (rfd2obj) PyMem_DEL(rfd2obj);
317 if (wfd2obj) PyMem_DEL(wfd2obj);
318 if (efd2obj) PyMem_DEL(efd2obj);
319 return PyErr_NoMemory();
320 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000321#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 /* Convert sequences to fd_sets, and get maximum fd number
324 * propagates the Python exception set in seq2set()
325 */
326 rfd2obj[0].sentinel = -1;
327 wfd2obj[0].sentinel = -1;
328 efd2obj[0].sentinel = -1;
Tal Einat6dc57e22018-06-30 23:02:48 +0300329 if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300331 if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300333 if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 max = imax;
337 if (omax > max) max = omax;
338 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000339
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200340 if (tvp)
341 deadline = _PyTime_GetMonotonicClock() + timeout;
342
343 do {
344 Py_BEGIN_ALLOW_THREADS
345 errno = 0;
346 n = select(max, &ifdset, &ofdset, &efdset, tvp);
347 Py_END_ALLOW_THREADS
348
349 if (errno != EINTR)
350 break;
351
352 /* select() was interrupted by a signal */
353 if (PyErr_CheckSignals())
354 goto finally;
355
356 if (tvp) {
357 timeout = deadline - _PyTime_GetMonotonicClock();
358 if (timeout < 0) {
Oran Avraham7f524152018-12-05 22:36:03 +0200359 /* bpo-35310: lists were unmodified -- clear them explicitly */
360 FD_ZERO(&ifdset);
361 FD_ZERO(&ofdset);
362 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200363 n = 0;
364 break;
365 }
366 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200367 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200368 }
369 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000370
Thomas Heller106f4c72002-09-24 16:51:00 +0000371#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200373 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000375#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200377 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000379#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 else {
381 /* any of these three calls can raise an exception. it's more
382 convenient to test for this after all three calls... but
383 is that acceptable?
384 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300385 rlist = set2list(&ifdset, rfd2obj);
386 wlist = set2list(&ofdset, wfd2obj);
387 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (PyErr_Occurred())
389 ret = NULL;
390 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300391 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000392
Tal Einat6dc57e22018-06-30 23:02:48 +0300393 Py_XDECREF(rlist);
394 Py_XDECREF(wlist);
395 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 }
397
Barry Warsawc1cb3601996-12-12 22:16:21 +0000398 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 reap_obj(rfd2obj);
400 reap_obj(wfd2obj);
401 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000402#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 PyMem_DEL(rfd2obj);
404 PyMem_DEL(wfd2obj);
405 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000406#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000408}
409
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000410#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000412 * poll() support
413 */
414
415typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 PyObject_HEAD
417 PyObject *dict;
418 int ufd_uptodate;
419 int ufd_len;
420 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300421 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000422} pollObject;
423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000425 contained within a pollObject. Return 1 on success, 0 on an error.
426*/
427
428static int
429update_ufd_array(pollObject *self)
430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 Py_ssize_t i, pos;
432 PyObject *key, *value;
433 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000434
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200435 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
437 if (self->ufds == NULL) {
438 self->ufds = old_ufds;
439 PyErr_NoMemory();
440 return 0;
441 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 i = pos = 0;
444 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200445 assert(i < self->ufd_len);
446 /* Never overflow */
447 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200448 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 i++;
450 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200451 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 self->ufd_uptodate = 1;
453 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000454}
455
Tal Einat6dc57e22018-06-30 23:02:48 +0300456/*[clinic input]
457select.poll.register
458
459 fd: fildes
460 either an integer, or an object with a fileno() method returning an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300461 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300462 an optional bitmask describing the type of events to check for
463 /
464
465Register a file descriptor with the polling object.
466[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000467
468static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300469select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300470/*[clinic end generated code: output=0dc7173c800a4a65 input=f18711d9bb021e25]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000471{
Tal Einat6dc57e22018-06-30 23:02:48 +0300472 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 /* Add entry to the internal dictionary: the key is the
476 file descriptor, and the value is the event mask. */
477 key = PyLong_FromLong(fd);
478 if (key == NULL)
479 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300480 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 if (value == NULL) {
482 Py_DECREF(key);
483 return NULL;
484 }
485 err = PyDict_SetItem(self->dict, key, value);
486 Py_DECREF(key);
487 Py_DECREF(value);
488 if (err < 0)
489 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 self->ufd_uptodate = 0;
492
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200493 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494}
495
Tal Einat6dc57e22018-06-30 23:02:48 +0300496
497/*[clinic input]
498select.poll.modify
499
500 fd: fildes
501 either an integer, or an object with a fileno() method returning
502 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300503 eventmask: unsigned_short
Tal Einat6dc57e22018-06-30 23:02:48 +0300504 a bitmask describing the type of events to check for
505 /
506
507Modify an already registered file descriptor.
508[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000509
510static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300511select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300512/*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000513{
Tal Einat6dc57e22018-06-30 23:02:48 +0300514 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 /* Modify registered fd */
518 key = PyLong_FromLong(fd);
519 if (key == NULL)
520 return NULL;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200521 if (PyDict_GetItemWithError(self->dict, key) == NULL) {
522 if (!PyErr_Occurred()) {
523 errno = ENOENT;
524 PyErr_SetFromErrno(PyExc_OSError);
525 }
Jesus Cea62a5c322012-07-19 21:31:26 +0200526 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 return NULL;
528 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300529 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 if (value == NULL) {
531 Py_DECREF(key);
532 return NULL;
533 }
534 err = PyDict_SetItem(self->dict, key, value);
535 Py_DECREF(key);
536 Py_DECREF(value);
537 if (err < 0)
538 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 self->ufd_uptodate = 0;
541
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200542 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000543}
544
545
Tal Einat6dc57e22018-06-30 23:02:48 +0300546/*[clinic input]
547select.poll.unregister
548
549 fd: fildes
550 /
551
552Remove a file descriptor being tracked by the polling object.
553[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000554
555static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300556select_poll_unregister_impl(pollObject *self, int fd)
557/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 /* Check whether the fd is already in the array */
562 key = PyLong_FromLong(fd);
563 if (key == NULL)
564 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 if (PyDict_DelItem(self->dict, key) == -1) {
567 Py_DECREF(key);
568 /* This will simply raise the KeyError set by PyDict_DelItem
569 if the file descriptor isn't registered. */
570 return NULL;
571 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 Py_DECREF(key);
574 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000575
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200576 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000577}
578
Tal Einat6dc57e22018-06-30 23:02:48 +0300579/*[clinic input]
580select.poll.poll
581
582 timeout as timeout_obj: object = None
583 /
584
585Polls the set of registered file descriptors.
586
587Returns a list containing any descriptors that have events or errors to
588report, as a list of (fd, event) 2-tuples.
589[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000590
591static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300592select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
593/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000594{
Tal Einat6dc57e22018-06-30 23:02:48 +0300595 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200596 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200598 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200599 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000600
Tal Einat6dc57e22018-06-30 23:02:48 +0300601 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200602 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100603 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200604 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
605 PyErr_SetString(PyExc_TypeError,
606 "timeout must be an integer or None");
607 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200609 }
610
Pablo Galindo2c15b292017-10-17 15:14:41 +0100611 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200612 if (ms < INT_MIN || ms > INT_MAX) {
613 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200615 }
616
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200617 if (timeout >= 0) {
618 deadline = _PyTime_GetMonotonicClock() + timeout;
619 }
620 }
621
622 /* On some OSes, typically BSD-based ones, the timeout parameter of the
623 poll() syscall, when negative, must be exactly INFTIM, where defined,
624 or -1. See issue 31334. */
625 if (ms < 0) {
626#ifdef INFTIM
627 ms = INFTIM;
628#else
629 ms = -1;
630#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000632
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300633 /* Avoid concurrent poll() invocation, issue 8865 */
634 if (self->poll_running) {
635 PyErr_SetString(PyExc_RuntimeError,
636 "concurrent poll() invocation");
637 return NULL;
638 }
639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 /* Ensure the ufd array is up to date */
641 if (!self->ufd_uptodate)
642 if (update_ufd_array(self) == 0)
643 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000644
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300645 self->poll_running = 1;
646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200648 async_err = 0;
649 do {
650 Py_BEGIN_ALLOW_THREADS
651 errno = 0;
652 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
653 Py_END_ALLOW_THREADS
654
655 if (errno != EINTR)
656 break;
657
658 /* poll() was interrupted by a signal */
659 if (PyErr_CheckSignals()) {
660 async_err = 1;
661 break;
662 }
663
664 if (timeout >= 0) {
665 timeout = deadline - _PyTime_GetMonotonicClock();
666 if (timeout < 0) {
667 poll_result = 0;
668 break;
669 }
670 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
671 /* retry poll() with the recomputed timeout */
672 }
673 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000674
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300675 self->poll_running = 0;
676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200678 if (!async_err)
679 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 return NULL;
681 }
682
683 /* build the result list */
684
685 result_list = PyList_New(poll_result);
686 if (!result_list)
687 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200689 for (i = 0, j = 0; j < poll_result; j++) {
690 /* skip to the next fired descriptor */
691 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 i++;
693 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200694 /* if we hit a NULL return, set value to NULL
695 and break out of loop; code at end will
696 clean up result_list */
697 value = PyTuple_New(2);
698 if (value == NULL)
699 goto error;
700 num = PyLong_FromLong(self->ufds[i].fd);
701 if (num == NULL) {
702 Py_DECREF(value);
703 goto error;
704 }
705 PyTuple_SET_ITEM(value, 0, num);
706
707 /* The &0xffff is a workaround for AIX. 'revents'
708 is a 16-bit short, and IBM assigned POLLNVAL
709 to be 0x8000, so the conversion to int results
710 in a negative number. See SF bug #923315. */
711 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
712 if (num == NULL) {
713 Py_DECREF(value);
714 goto error;
715 }
716 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700717 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200718 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 }
720 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000721
722 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 Py_DECREF(result_list);
724 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000725}
726
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000727static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000728newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 pollObject *self;
Dino Viehlandf9190542019-09-14 15:20:27 +0100731 self = PyObject_New(pollObject, _selectstate_global->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 if (self == NULL)
733 return NULL;
734 /* ufd_uptodate is a Boolean, denoting whether the
735 array pointed to by ufds matches the contents of the dictionary. */
736 self->ufd_uptodate = 0;
737 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300738 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 self->dict = PyDict_New();
740 if (self->dict == NULL) {
741 Py_DECREF(self);
742 return NULL;
743 }
744 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000745}
746
Dino Viehlandf9190542019-09-14 15:20:27 +0100747static PyObject *
748poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
749{
750 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
751 return NULL;
752}
753
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000754static void
755poll_dealloc(pollObject *self)
756{
Dino Viehlandf9190542019-09-14 15:20:27 +0100757 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 if (self->ufds != NULL)
759 PyMem_DEL(self->ufds);
760 Py_XDECREF(self->dict);
761 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100762 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000763}
764
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000765
Jesus Cead8b9ae62011-11-14 19:07:41 +0100766#ifdef HAVE_SYS_DEVPOLL_H
767typedef struct {
768 PyObject_HEAD
769 int fd_devpoll;
770 int max_n_fds;
771 int n_fds;
772 struct pollfd *fds;
773} devpollObject;
774
Victor Stinner13423c32013-08-22 00:19:50 +0200775static PyObject *
776devpoll_err_closed(void)
777{
778 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
779 return NULL;
780}
781
Jesus Cead8b9ae62011-11-14 19:07:41 +0100782static int devpoll_flush(devpollObject *self)
783{
784 int size, n;
785
786 if (!self->n_fds) return 0;
787
788 size = sizeof(struct pollfd)*self->n_fds;
789 self->n_fds = 0;
790
Victor Stinner54799672015-03-19 23:33:09 +0100791 n = _Py_write(self->fd_devpoll, self->fds, size);
792 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100793 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100794
Jesus Cead8b9ae62011-11-14 19:07:41 +0100795 if (n < size) {
796 /*
797 ** Data writed to /dev/poll is a binary data structure. It is not
798 ** clear what to do if a partial write occurred. For now, raise
799 ** an exception and see if we actually found this problem in
800 ** the wild.
801 ** See http://bugs.python.org/issue6397.
802 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300803 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100804 "Please, report at http://bugs.python.org/. "
805 "Data to report: Size tried: %d, actual size written: %d.",
806 size, n);
807 return -1;
808 }
809 return 0;
810}
811
812static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300813internal_devpoll_register(devpollObject *self, int fd,
814 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100815{
Victor Stinner13423c32013-08-22 00:19:50 +0200816 if (self->fd_devpoll < 0)
817 return devpoll_err_closed();
818
Jesus Cead8b9ae62011-11-14 19:07:41 +0100819 if (remove) {
820 self->fds[self->n_fds].fd = fd;
821 self->fds[self->n_fds].events = POLLREMOVE;
822
823 if (++self->n_fds == self->max_n_fds) {
824 if (devpoll_flush(self))
825 return NULL;
826 }
827 }
828
829 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200830 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100831
832 if (++self->n_fds == self->max_n_fds) {
833 if (devpoll_flush(self))
834 return NULL;
835 }
836
837 Py_RETURN_NONE;
838}
839
Tal Einat6dc57e22018-06-30 23:02:48 +0300840/*[clinic input]
841select.devpoll.register
842
843 fd: fildes
844 either an integer, or an object with a fileno() method returning
845 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300846 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300847 an optional bitmask describing the type of events to check for
848 /
849
850Register a file descriptor with the polling object.
851[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100852
853static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300854select_devpoll_register_impl(devpollObject *self, int fd,
855 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300856/*[clinic end generated code: output=6e07fe8b74abba0c input=5bd7cacc47a8ee46]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100857{
Tal Einat6dc57e22018-06-30 23:02:48 +0300858 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859}
860
Tal Einat6dc57e22018-06-30 23:02:48 +0300861/*[clinic input]
862select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863
Tal Einat6dc57e22018-06-30 23:02:48 +0300864 fd: fildes
865 either an integer, or an object with a fileno() method returning
866 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300867 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300868 an optional bitmask describing the type of events to check for
869 /
870
871Modify a possible already registered file descriptor.
872[clinic start generated code]*/
873
874static PyObject *
875select_devpoll_modify_impl(devpollObject *self, int fd,
876 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300877/*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100878{
Tal Einat6dc57e22018-06-30 23:02:48 +0300879 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100880}
881
Tal Einat6dc57e22018-06-30 23:02:48 +0300882/*[clinic input]
883select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100884
Tal Einat6dc57e22018-06-30 23:02:48 +0300885 fd: fildes
886 /
887
888Remove a file descriptor being tracked by the polling object.
889[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100890
891static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300892select_devpoll_unregister_impl(devpollObject *self, int fd)
893/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100894{
Victor Stinner13423c32013-08-22 00:19:50 +0200895 if (self->fd_devpoll < 0)
896 return devpoll_err_closed();
897
Jesus Cead8b9ae62011-11-14 19:07:41 +0100898 self->fds[self->n_fds].fd = fd;
899 self->fds[self->n_fds].events = POLLREMOVE;
900
901 if (++self->n_fds == self->max_n_fds) {
902 if (devpoll_flush(self))
903 return NULL;
904 }
905
906 Py_RETURN_NONE;
907}
908
Tal Einat6dc57e22018-06-30 23:02:48 +0300909/*[clinic input]
910select.devpoll.poll
911 timeout as timeout_obj: object = None
912 /
913
914Polls the set of registered file descriptors.
915
916Returns a list containing any descriptors that have events or errors to
917report, as a list of (fd, event) 2-tuples.
918[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919
920static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300921select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
922/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100923{
924 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200925 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100926 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100927 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200928 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100929
Victor Stinner13423c32013-08-22 00:19:50 +0200930 if (self->fd_devpoll < 0)
931 return devpoll_err_closed();
932
Jesus Cead8b9ae62011-11-14 19:07:41 +0100933 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300934 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100935 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200936 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100937 }
938 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200939 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100940 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200941 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
942 PyErr_SetString(PyExc_TypeError,
943 "timeout must be an integer or None");
944 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100945 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200946 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100947
Pablo Galindo2c15b292017-10-17 15:14:41 +0100948 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200949 if (ms < -1 || ms > INT_MAX) {
950 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
951 return NULL;
952 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100953 }
954
955 if (devpoll_flush(self))
956 return NULL;
957
958 dvp.dp_fds = self->fds;
959 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200960 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100961
Victor Stinner45ca48b2015-03-31 12:10:33 +0200962 if (timeout >= 0)
963 deadline = _PyTime_GetMonotonicClock() + timeout;
964
965 do {
966 /* call devpoll() */
967 Py_BEGIN_ALLOW_THREADS
968 errno = 0;
969 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
970 Py_END_ALLOW_THREADS
971
972 if (errno != EINTR)
973 break;
974
975 /* devpoll() was interrupted by a signal */
976 if (PyErr_CheckSignals())
977 return NULL;
978
979 if (timeout >= 0) {
980 timeout = deadline - _PyTime_GetMonotonicClock();
981 if (timeout < 0) {
982 poll_result = 0;
983 break;
984 }
985 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
986 dvp.dp_timeout = (int)ms;
987 /* retry devpoll() with the recomputed timeout */
988 }
989 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100990
991 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300992 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100993 return NULL;
994 }
995
996 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100997 result_list = PyList_New(poll_result);
998 if (!result_list)
999 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +02001000
1001 for (i = 0; i < poll_result; i++) {
1002 num1 = PyLong_FromLong(self->fds[i].fd);
1003 num2 = PyLong_FromLong(self->fds[i].revents);
1004 if ((num1 == NULL) || (num2 == NULL)) {
1005 Py_XDECREF(num1);
1006 Py_XDECREF(num2);
1007 goto error;
1008 }
1009 value = PyTuple_Pack(2, num1, num2);
1010 Py_DECREF(num1);
1011 Py_DECREF(num2);
1012 if (value == NULL)
1013 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001014 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001015 }
1016
1017 return result_list;
1018
1019 error:
1020 Py_DECREF(result_list);
1021 return NULL;
1022}
1023
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001024static int
1025devpoll_internal_close(devpollObject *self)
1026{
1027 int save_errno = 0;
1028 if (self->fd_devpoll >= 0) {
1029 int fd = self->fd_devpoll;
1030 self->fd_devpoll = -1;
1031 Py_BEGIN_ALLOW_THREADS
1032 if (close(fd) < 0)
1033 save_errno = errno;
1034 Py_END_ALLOW_THREADS
1035 }
1036 return save_errno;
1037}
1038
Tal Einat6dc57e22018-06-30 23:02:48 +03001039/*[clinic input]
1040select.devpoll.close
1041
1042Close the devpoll file descriptor.
1043
1044Further operations on the devpoll object will raise an exception.
1045[clinic start generated code]*/
1046
1047static PyObject *
1048select_devpoll_close_impl(devpollObject *self)
1049/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001050{
1051 errno = devpoll_internal_close(self);
1052 if (errno < 0) {
1053 PyErr_SetFromErrno(PyExc_OSError);
1054 return NULL;
1055 }
1056 Py_RETURN_NONE;
1057}
1058
Victor Stinner13423c32013-08-22 00:19:50 +02001059static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001060devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001061{
1062 if (self->fd_devpoll < 0)
1063 Py_RETURN_TRUE;
1064 else
1065 Py_RETURN_FALSE;
1066}
1067
Tal Einat6dc57e22018-06-30 23:02:48 +03001068/*[clinic input]
1069select.devpoll.fileno
1070
1071Return the file descriptor.
1072[clinic start generated code]*/
1073
1074static PyObject *
1075select_devpoll_fileno_impl(devpollObject *self)
1076/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001077{
1078 if (self->fd_devpoll < 0)
1079 return devpoll_err_closed();
1080 return PyLong_FromLong(self->fd_devpoll);
1081}
1082
Victor Stinner13423c32013-08-22 00:19:50 +02001083static PyGetSetDef devpoll_getsetlist[] = {
1084 {"closed", (getter)devpoll_get_closed, NULL,
1085 "True if the devpoll object is closed"},
1086 {0},
1087};
1088
Jesus Cead8b9ae62011-11-14 19:07:41 +01001089static devpollObject *
1090newDevPollObject(void)
1091{
1092 devpollObject *self;
1093 int fd_devpoll, limit_result;
1094 struct pollfd *fds;
1095 struct rlimit limit;
1096
Jesus Cead8b9ae62011-11-14 19:07:41 +01001097 /*
1098 ** If we try to process more that getrlimit()
1099 ** fds, the kernel will give an error, so
1100 ** we set the limit here. It is a dynamic
1101 ** value, because we can change rlimit() anytime.
1102 */
1103 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001104 if (limit_result == -1) {
1105 PyErr_SetFromErrno(PyExc_OSError);
1106 return NULL;
1107 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001108
1109 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1110 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001111 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001112
1113 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1114 if (fds == NULL) {
1115 close(fd_devpoll);
1116 PyErr_NoMemory();
1117 return NULL;
1118 }
1119
Dino Viehlandf9190542019-09-14 15:20:27 +01001120 self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001121 if (self == NULL) {
1122 close(fd_devpoll);
1123 PyMem_DEL(fds);
1124 return NULL;
1125 }
1126 self->fd_devpoll = fd_devpoll;
1127 self->max_n_fds = limit.rlim_cur;
1128 self->n_fds = 0;
1129 self->fds = fds;
1130
1131 return self;
1132}
1133
Dino Viehlandf9190542019-09-14 15:20:27 +01001134static PyObject *
1135devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1136{
1137 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1138 return NULL;
1139}
1140
Jesus Cead8b9ae62011-11-14 19:07:41 +01001141static void
1142devpoll_dealloc(devpollObject *self)
1143{
Dino Viehlandf9190542019-09-14 15:20:27 +01001144 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001145 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001146 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001147 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001148 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001149}
1150
Dino Viehlandf9190542019-09-14 15:20:27 +01001151static PyType_Slot devpoll_Type_slots[] = {
1152 {Py_tp_dealloc, devpoll_dealloc},
1153 {Py_tp_getset, devpoll_getsetlist},
1154 {Py_tp_methods, devpoll_methods},
1155 {Py_tp_new, devpoll_new},
1156 {0, 0},
1157};
1158
1159static PyType_Spec devpoll_Type_spec = {
1160 "select.devpoll",
1161 sizeof(devpollObject),
1162 0,
1163 Py_TPFLAGS_DEFAULT,
1164 devpoll_Type_slots
1165};
1166
Jesus Cead8b9ae62011-11-14 19:07:41 +01001167#endif /* HAVE_SYS_DEVPOLL_H */
1168
1169
Tal Einat6dc57e22018-06-30 23:02:48 +03001170/*[clinic input]
1171select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001172
Tal Einat6dc57e22018-06-30 23:02:48 +03001173Returns a polling object.
1174
1175This object supports registering and unregistering file descriptors, and then
1176polling them for I/O events.
1177[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001178
1179static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001180select_poll_impl(PyObject *module)
1181/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001184}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185
Jesus Cead8b9ae62011-11-14 19:07:41 +01001186#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001187
1188/*[clinic input]
1189select.devpoll
1190
1191Returns a polling object.
1192
1193This object supports registering and unregistering file descriptors, and then
1194polling them for I/O events.
1195[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001196
1197static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001198select_devpoll_impl(PyObject *module)
1199/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001200{
1201 return (PyObject *)newDevPollObject();
1202}
1203#endif
1204
1205
Thomas Wouters477c8d52006-05-27 19:21:47 +00001206#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208 * On some systems poll() sets errno on invalid file descriptors. We test
1209 * for this at runtime because this bug may be fixed or introduced between
1210 * OS releases.
1211 */
1212static int select_have_broken_poll(void)
1213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 int poll_test;
1215 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 /* Create a file descriptor to make invalid */
1220 if (pipe(filedes) < 0) {
1221 return 1;
1222 }
1223 poll_struct.fd = filedes[0];
1224 close(filedes[0]);
1225 close(filedes[1]);
1226 poll_test = poll(&poll_struct, 1, 0);
1227 if (poll_test < 0) {
1228 return 1;
1229 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1230 return 1;
1231 }
1232 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001233}
1234#endif /* __APPLE__ */
1235
1236#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001237
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001238#ifdef HAVE_EPOLL
1239/* **************************************************************************
1240 * epoll interface for Linux 2.6
1241 *
1242 * Written by Christian Heimes
1243 * Inspired by Twisted's _epoll.pyx and select.poll()
1244 */
1245
1246#ifdef HAVE_SYS_EPOLL_H
1247#include <sys/epoll.h>
1248#endif
1249
1250typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001252 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001253} pyEpoll_Object;
1254
Dino Viehlandf9190542019-09-14 15:20:27 +01001255#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256
1257static PyObject *
1258pyepoll_err_closed(void)
1259{
Victor Stinner13423c32013-08-22 00:19:50 +02001260 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262}
1263
1264static int
1265pyepoll_internal_close(pyEpoll_Object *self)
1266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 int save_errno = 0;
1268 if (self->epfd >= 0) {
1269 int epfd = self->epfd;
1270 self->epfd = -1;
1271 Py_BEGIN_ALLOW_THREADS
1272 if (close(epfd) < 0)
1273 save_errno = errno;
1274 Py_END_ALLOW_THREADS
1275 }
1276 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001277}
1278
1279static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001280newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001283 assert(type != NULL);
1284 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1285 assert(epoll_alloc != NULL);
1286 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 if (self == NULL)
1288 return NULL;
1289
1290 if (fd == -1) {
1291 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001292#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001293 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1294#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001295 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001296#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 Py_END_ALLOW_THREADS
1298 }
1299 else {
1300 self->epfd = fd;
1301 }
1302 if (self->epfd < 0) {
1303 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001304 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 return NULL;
1306 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001307
1308#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001309 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001310 Py_DECREF(self);
1311 return NULL;
1312 }
1313#endif
1314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001316}
1317
1318
Tal Einat6dc57e22018-06-30 23:02:48 +03001319/*[clinic input]
1320@classmethod
1321select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001322
Tal Einat6dc57e22018-06-30 23:02:48 +03001323 sizehint: int = -1
1324 The expected number of events to be registered. It must be positive,
1325 or -1 to use the default. It is only used on older systems where
1326 epoll_create1() is not available; otherwise it has no effect (though its
1327 value is still checked).
1328 flags: int = 0
1329 Deprecated and completely ignored. However, when supplied, its value
1330 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1331
1332Returns an epolling object.
1333[clinic start generated code]*/
1334
1335static PyObject *
1336select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1337/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1338{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001339 if (sizehint == -1) {
1340 sizehint = FD_SETSIZE - 1;
1341 }
1342 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001343 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001344 return NULL;
1345 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001346
1347#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001348 if (flags && flags != EPOLL_CLOEXEC) {
1349 PyErr_SetString(PyExc_OSError, "invalid flags");
1350 return NULL;
1351 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001352#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001353
Berker Peksage2197d12016-09-26 23:30:41 +03001354 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001355}
1356
1357
1358static void
1359pyepoll_dealloc(pyEpoll_Object *self)
1360{
Dino Viehlandf9190542019-09-14 15:20:27 +01001361 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001363 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1364 epoll_free((PyObject *)self);
1365 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001366}
1367
Tal Einat6dc57e22018-06-30 23:02:48 +03001368/*[clinic input]
1369select.epoll.close
1370
1371Close the epoll control file descriptor.
1372
1373Further operations on the epoll object will raise an exception.
1374[clinic start generated code]*/
1375
1376static PyObject *
1377select_epoll_close_impl(pyEpoll_Object *self)
1378/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 errno = pyepoll_internal_close(self);
1381 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001382 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 return NULL;
1384 }
1385 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386}
1387
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388
1389static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001390pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 if (self->epfd < 0)
1393 Py_RETURN_TRUE;
1394 else
1395 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001396}
1397
Tal Einat6dc57e22018-06-30 23:02:48 +03001398/*[clinic input]
1399select.epoll.fileno
1400
1401Return the epoll control file descriptor.
1402[clinic start generated code]*/
1403
1404static PyObject *
1405select_epoll_fileno_impl(pyEpoll_Object *self)
1406/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 if (self->epfd < 0)
1409 return pyepoll_err_closed();
1410 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001411}
1412
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001413
Tal Einat6dc57e22018-06-30 23:02:48 +03001414/*[clinic input]
1415@classmethod
1416select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001417
Tal Einat6dc57e22018-06-30 23:02:48 +03001418 fd: int
1419 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001420
Tal Einat6dc57e22018-06-30 23:02:48 +03001421Create an epoll object from a given control fd.
1422[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001423
1424static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001425select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1426/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1427{
1428 SOCKET s_fd = (SOCKET)fd;
1429 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1430}
1431
1432
1433static PyObject *
1434pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 struct epoll_event ev;
1437 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 if (epfd < 0)
1440 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441
Guido van Rossumee07b942013-12-06 17:46:22 -08001442 switch (op) {
1443 case EPOLL_CTL_ADD:
1444 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 ev.events = events;
1446 ev.data.fd = fd;
1447 Py_BEGIN_ALLOW_THREADS
1448 result = epoll_ctl(epfd, op, fd, &ev);
1449 Py_END_ALLOW_THREADS
1450 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001451 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1453 * operation required a non-NULL pointer in event, even
1454 * though this argument is ignored. */
1455 Py_BEGIN_ALLOW_THREADS
1456 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 Py_END_ALLOW_THREADS
1458 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001459 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 result = -1;
1461 errno = EINVAL;
1462 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001465 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 return NULL;
1467 }
1468 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001469}
1470
Tal Einat6dc57e22018-06-30 23:02:48 +03001471/*[clinic input]
1472select.epoll.register
1473
1474 fd: fildes
1475 the target file descriptor of the operation
1476 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1477 a bit set composed of the various EPOLL constants
1478
1479Registers a new fd or raises an OSError if the fd is already registered.
1480
1481The epoll interface supports all file descriptors that support poll.
1482[clinic start generated code]*/
1483
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001485select_epoll_register_impl(pyEpoll_Object *self, int fd,
1486 unsigned int eventmask)
1487/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001488{
Tal Einat6dc57e22018-06-30 23:02:48 +03001489 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001490}
1491
Tal Einat6dc57e22018-06-30 23:02:48 +03001492/*[clinic input]
1493select.epoll.modify
1494
1495 fd: fildes
1496 the target file descriptor of the operation
1497 eventmask: unsigned_int(bitwise=True)
1498 a bit set composed of the various EPOLL constants
1499
1500Modify event mask for a registered file descriptor.
1501[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502
1503static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001504select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1505 unsigned int eventmask)
1506/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507{
Tal Einat6dc57e22018-06-30 23:02:48 +03001508 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509}
1510
Tal Einat6dc57e22018-06-30 23:02:48 +03001511/*[clinic input]
1512select.epoll.unregister
1513
1514 fd: fildes
1515 the target file descriptor of the operation
1516
1517Remove a registered file descriptor from the epoll object.
1518[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001519
1520static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001521select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1522/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001523{
Tal Einat6dc57e22018-06-30 23:02:48 +03001524 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001525}
1526
Tal Einat6dc57e22018-06-30 23:02:48 +03001527/*[clinic input]
1528select.epoll.poll
1529
1530 timeout as timeout_obj: object = None
1531 the maximum time to wait in seconds (as float);
1532 a timeout of None or -1 makes poll wait indefinitely
1533 maxevents: int = -1
1534 the maximum number of events returned; -1 means no limit
1535
1536Wait for events on the epoll file descriptor.
1537
1538Returns a list containing any descriptors that have events to report,
1539as a list of (fd, events) 2-tuples.
1540[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001541
1542static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001543select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1544 int maxevents)
1545/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 int nfds, i;
1548 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001549 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001550 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 if (self->epfd < 0)
1553 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001554
Berker Peksagb690b9b2018-09-11 20:29:48 +03001555 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001556 /* epoll_wait() has a resolution of 1 millisecond, round towards
1557 infinity to wait at least timeout seconds. */
1558 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001559 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001560 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1561 PyErr_SetString(PyExc_TypeError,
1562 "timeout must be an integer or None");
1563 }
1564 return NULL;
1565 }
1566
1567 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1568 if (ms < INT_MIN || ms > INT_MAX) {
1569 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1570 return NULL;
1571 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001572 /* epoll_wait(2) treats all arbitrary negative numbers the same
1573 for the timeout argument, but -1 is the documented way to block
1574 indefinitely in the epoll_wait(2) documentation, so we set ms
1575 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001576
Berker Peksagb690b9b2018-09-11 20:29:48 +03001577 Note that we didn't use INFTIM here since it's non-standard and
1578 isn't available under Linux. */
1579 if (ms < 0) {
1580 ms = -1;
1581 }
1582
1583 if (timeout >= 0) {
1584 deadline = _PyTime_GetMonotonicClock() + timeout;
1585 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001589 maxevents = FD_SETSIZE-1;
1590 }
1591 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 PyErr_Format(PyExc_ValueError,
1593 "maxevents must be greater than 0, got %d",
1594 maxevents);
1595 return NULL;
1596 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001597
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001598 evs = PyMem_New(struct epoll_event, maxevents);
1599 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001600 PyErr_NoMemory();
1601 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001603
Victor Stinner41eba222015-03-30 21:59:21 +02001604 do {
1605 Py_BEGIN_ALLOW_THREADS
1606 errno = 0;
1607 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1608 Py_END_ALLOW_THREADS
1609
1610 if (errno != EINTR)
1611 break;
1612
1613 /* poll() was interrupted by a signal */
1614 if (PyErr_CheckSignals())
1615 goto error;
1616
1617 if (timeout >= 0) {
1618 timeout = deadline - _PyTime_GetMonotonicClock();
1619 if (timeout < 0) {
1620 nfds = 0;
1621 break;
1622 }
1623 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1624 /* retry epoll_wait() with the recomputed timeout */
1625 }
1626 } while(1);
1627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001629 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 goto error;
1631 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 elist = PyList_New(nfds);
1634 if (elist == NULL) {
1635 goto error;
1636 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001639 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 if (etuple == NULL) {
1641 Py_CLEAR(elist);
1642 goto error;
1643 }
1644 PyList_SET_ITEM(elist, i, etuple);
1645 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001646
Christian Heimesf6cd9672008-03-26 13:45:42 +00001647 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001648 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001650}
1651
Tal Einat6dc57e22018-06-30 23:02:48 +03001652
1653/*[clinic input]
1654select.epoll.__enter__
1655
1656[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001657
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001658static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001659select_epoll___enter___impl(pyEpoll_Object *self)
1660/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001661{
1662 if (self->epfd < 0)
1663 return pyepoll_err_closed();
1664
1665 Py_INCREF(self);
1666 return (PyObject *)self;
1667}
1668
Tal Einat6dc57e22018-06-30 23:02:48 +03001669/*[clinic input]
1670select.epoll.__exit__
1671
1672 exc_type: object = None
1673 exc_value: object = None
1674 exc_tb: object = None
1675 /
1676
1677[clinic start generated code]*/
1678
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001679static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001680select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1681 PyObject *exc_value, PyObject *exc_tb)
1682/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001683{
Dino Viehlandf9190542019-09-14 15:20:27 +01001684 return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001685}
1686
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001687static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 {"closed", (getter)pyepoll_get_closed, NULL,
1689 "True if the epoll handler is closed"},
1690 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001691};
1692
Dino Viehlandf9190542019-09-14 15:20:27 +01001693PyDoc_STRVAR(pyepoll_doc,
1694"select.epoll(sizehint=-1, flags=0)\n\
1695\n\
1696Returns an epolling object\n\
1697\n\
1698sizehint must be a positive integer or -1 for the default size. The\n\
1699sizehint is used to optimize internal data structures. It doesn't limit\n\
1700the maximum number of monitored events.");
1701
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001702#endif /* HAVE_EPOLL */
1703
1704#ifdef HAVE_KQUEUE
1705/* **************************************************************************
1706 * kqueue interface for BSD
1707 *
1708 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1709 * All rights reserved.
1710 *
1711 * Redistribution and use in source and binary forms, with or without
1712 * modification, are permitted provided that the following conditions
1713 * are met:
1714 * 1. Redistributions of source code must retain the above copyright
1715 * notice, this list of conditions and the following disclaimer.
1716 * 2. Redistributions in binary form must reproduce the above copyright
1717 * notice, this list of conditions and the following disclaimer in the
1718 * documentation and/or other materials provided with the distribution.
1719 *
1720 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1721 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1722 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1723 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1724 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1725 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1726 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1727 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1728 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1729 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1730 * SUCH DAMAGE.
1731 */
1732
1733#ifdef HAVE_SYS_EVENT_H
1734#include <sys/event.h>
1735#endif
1736
1737PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001738"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001739\n\
1740This object is the equivalent of the struct kevent for the C API.\n\
1741\n\
1742See the kqueue manpage for more detailed information about the meaning\n\
1743of the arguments.\n\
1744\n\
1745One minor note: while you might hope that udata could store a\n\
1746reference to a python object, it cannot, because it is impossible to\n\
1747keep a proper reference count of the object once it's passed into the\n\
1748kernel. Therefore, I have restricted it to only storing an integer. I\n\
1749recommend ignoring it and simply using the 'ident' field to key off\n\
1750of. You could also set up a dictionary on the python side to store a\n\
1751udata->object mapping.");
1752
1753typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 PyObject_HEAD
1755 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001756} kqueue_event_Object;
1757
Dino Viehlandf9190542019-09-14 15:20:27 +01001758#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001759
1760typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 PyObject_HEAD
1762 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001763} kqueue_queue_Object;
1764
Dino Viehlandf9190542019-09-14 15:20:27 +01001765#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001766
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001767#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1768# error uintptr_t does not match void *!
1769#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1770# define T_UINTPTRT T_ULONGLONG
1771# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001772# define UINTPTRT_FMT_UNIT "K"
1773# define INTPTRT_FMT_UNIT "L"
1774#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1775# define T_UINTPTRT T_ULONG
1776# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001777# define UINTPTRT_FMT_UNIT "k"
1778# define INTPTRT_FMT_UNIT "l"
1779#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1780# define T_UINTPTRT T_UINT
1781# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001782# define UINTPTRT_FMT_UNIT "I"
1783# define INTPTRT_FMT_UNIT "i"
1784#else
1785# error uintptr_t does not match int, long, or long long!
1786#endif
1787
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001788#if SIZEOF_LONG_LONG == 8
1789# define T_INT64 T_LONGLONG
1790# define INT64_FMT_UNIT "L"
1791#elif SIZEOF_LONG == 8
1792# define T_INT64 T_LONG
1793# define INT64_FMT_UNIT "l"
1794#elif SIZEOF_INT == 8
1795# define T_INT64 T_INT
1796# define INT64_FMT_UNIT "i"
1797#else
1798# define INT64_FMT_UNIT "_"
1799#endif
1800
1801#if SIZEOF_LONG_LONG == 4
1802# define T_UINT32 T_ULONGLONG
1803# define UINT32_FMT_UNIT "K"
1804#elif SIZEOF_LONG == 4
1805# define T_UINT32 T_ULONG
1806# define UINT32_FMT_UNIT "k"
1807#elif SIZEOF_INT == 4
1808# define T_UINT32 T_UINT
1809# define UINT32_FMT_UNIT "I"
1810#else
1811# define UINT32_FMT_UNIT "_"
1812#endif
1813
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001814/*
1815 * kevent is not standard and its members vary across BSDs.
1816 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001817#ifdef __NetBSD__
1818# define FILTER_TYPE T_UINT32
1819# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1820# define FLAGS_TYPE T_UINT32
1821# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1822# define FFLAGS_TYPE T_UINT32
1823# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001824#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001825# define FILTER_TYPE T_SHORT
1826# define FILTER_FMT_UNIT "h"
1827# define FLAGS_TYPE T_USHORT
1828# define FLAGS_FMT_UNIT "H"
1829# define FFLAGS_TYPE T_UINT
1830# define FFLAGS_FMT_UNIT "I"
1831#endif
1832
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001833#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001834# define DATA_TYPE T_INT64
1835# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001836#else
1837# define DATA_TYPE T_INTPTRT
1838# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001839#endif
1840
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841/* Unfortunately, we can't store python objects in udata, because
1842 * kevents in the kernel can be removed without warning, which would
1843 * forever lose the refcount on the object stored with it.
1844 */
1845
1846#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1847static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001848 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1849 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1850 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001852 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1854 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001855};
1856#undef KQ_OFF
1857
1858static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001859
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001860kqueue_event_repr(kqueue_event_Object *s)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 char buf[1024];
1863 PyOS_snprintf(
1864 buf, sizeof(buf),
1865 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001866 "data=0x%llx udata=%p>",
1867 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1868 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001870}
1871
1872static int
1873kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 PyObject *pfd;
1876 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1877 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001878 static const char fmt[] = "O|"
1879 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1880 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1885 &pfd, &(self->e.filter), &(self->e.flags),
1886 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1887 return -1;
1888 }
1889
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001890 if (PyLong_Check(pfd)) {
1891 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 }
1893 else {
1894 self->e.ident = PyObject_AsFileDescriptor(pfd);
1895 }
1896 if (PyErr_Occurred()) {
1897 return -1;
1898 }
1899 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001900}
1901
1902static PyObject *
1903kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001905{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001906 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001909 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001911
1912#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1913 result = CMP(s->e.ident, o->e.ident)
1914 : CMP(s->e.filter, o->e.filter)
1915 : CMP(s->e.flags, o->e.flags)
1916 : CMP(s->e.fflags, o->e.fflags)
1917 : CMP(s->e.data, o->e.data)
1918 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1919 : 0;
1920#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921
stratakise8b19652017-11-02 11:32:54 +01001922 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001923}
1924
Dino Viehlandf9190542019-09-14 15:20:27 +01001925static PyType_Slot kqueue_event_Type_slots[] = {
1926 {Py_tp_doc, (void*)kqueue_event_doc},
1927 {Py_tp_init, kqueue_event_init},
1928 {Py_tp_members, kqueue_event_members},
1929 {Py_tp_new, PyType_GenericNew},
1930 {Py_tp_repr, kqueue_event_repr},
1931 {Py_tp_richcompare, kqueue_event_richcompare},
1932 {0, 0},
1933};
1934
1935static PyType_Spec kqueue_event_Type_spec = {
1936 "select.kevent",
1937 sizeof(kqueue_event_Object),
1938 0,
1939 Py_TPFLAGS_DEFAULT,
1940 kqueue_event_Type_slots
1941};
1942
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001943static PyObject *
1944kqueue_queue_err_closed(void)
1945{
Victor Stinner13423c32013-08-22 00:19:50 +02001946 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001948}
1949
1950static int
1951kqueue_queue_internal_close(kqueue_queue_Object *self)
1952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 int save_errno = 0;
1954 if (self->kqfd >= 0) {
1955 int kqfd = self->kqfd;
1956 self->kqfd = -1;
1957 Py_BEGIN_ALLOW_THREADS
1958 if (close(kqfd) < 0)
1959 save_errno = errno;
1960 Py_END_ALLOW_THREADS
1961 }
1962 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001963}
1964
1965static PyObject *
1966newKqueue_Object(PyTypeObject *type, SOCKET fd)
1967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001969 assert(type != NULL);
1970 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1971 assert(queue_alloc != NULL);
1972 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 if (self == NULL) {
1974 return NULL;
1975 }
1976
1977 if (fd == -1) {
1978 Py_BEGIN_ALLOW_THREADS
1979 self->kqfd = kqueue();
1980 Py_END_ALLOW_THREADS
1981 }
1982 else {
1983 self->kqfd = fd;
1984 }
1985 if (self->kqfd < 0) {
1986 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001987 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 return NULL;
1989 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001990
1991 if (fd == -1) {
1992 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1993 Py_DECREF(self);
1994 return NULL;
1995 }
1996 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001998}
1999
Tal Einat6dc57e22018-06-30 23:02:48 +03002000/*[clinic input]
2001@classmethod
2002select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003
Tal Einat6dc57e22018-06-30 23:02:48 +03002004Kqueue syscall wrapper.
2005
2006For example, to start watching a socket for input:
2007>>> kq = kqueue()
2008>>> sock = socket()
2009>>> sock.connect((host, port))
2010>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
2011
2012To wait one second for it to become writeable:
2013>>> kq.control(None, 1, 1000)
2014
2015To stop listening:
2016>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2017[clinic start generated code]*/
2018
2019static PyObject *
2020select_kqueue_impl(PyTypeObject *type)
2021/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002024}
2025
2026static void
2027kqueue_queue_dealloc(kqueue_queue_Object *self)
2028{
Dino Viehlandf9190542019-09-14 15:20:27 +01002029 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002031 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2032 kqueue_free((PyObject *)self);
2033 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002034}
2035
Tal Einat6dc57e22018-06-30 23:02:48 +03002036/*[clinic input]
2037select.kqueue.close
2038
2039Close the kqueue control file descriptor.
2040
2041Further operations on the kqueue object will raise an exception.
2042[clinic start generated code]*/
2043
2044static PyObject *
2045select_kqueue_close_impl(kqueue_queue_Object *self)
2046/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 errno = kqueue_queue_internal_close(self);
2049 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002050 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 return NULL;
2052 }
2053 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002054}
2055
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002056static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002057kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 if (self->kqfd < 0)
2060 Py_RETURN_TRUE;
2061 else
2062 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002063}
2064
Tal Einat6dc57e22018-06-30 23:02:48 +03002065/*[clinic input]
2066select.kqueue.fileno
2067
2068Return the kqueue control file descriptor.
2069[clinic start generated code]*/
2070
2071static PyObject *
2072select_kqueue_fileno_impl(kqueue_queue_Object *self)
2073/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 if (self->kqfd < 0)
2076 return kqueue_queue_err_closed();
2077 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002078}
2079
Tal Einat6dc57e22018-06-30 23:02:48 +03002080/*[clinic input]
2081@classmethod
2082select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002083
Tal Einat6dc57e22018-06-30 23:02:48 +03002084 fd: int
2085 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002086
Tal Einat6dc57e22018-06-30 23:02:48 +03002087Create a kqueue object from a given control fd.
2088[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002089
2090static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002091select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2092/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002093{
Tal Einat6dc57e22018-06-30 23:02:48 +03002094 SOCKET s_fd = (SOCKET)fd;
2095
2096 return newKqueue_Object(type, s_fd);
2097}
2098
2099/*[clinic input]
2100select.kqueue.control
2101
2102 changelist: object
2103 Must be an iterable of kevent objects describing the changes to be made
2104 to the kernel's watch list or None.
2105 maxevents: int
2106 The maximum number of events that the kernel will return.
2107 timeout as otimeout: object = None
2108 The maximum time to wait in seconds, or else None to wait forever.
2109 This accepts floats for smaller timeouts, too.
2110 /
2111
2112Calls the kernel kevent function.
2113[clinic start generated code]*/
2114
2115static PyObject *
2116select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2117 int maxevents, PyObject *otimeout)
2118/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 int gotevents = 0;
2121 int nchanges = 0;
2122 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002123 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 PyObject *result = NULL;
2125 struct kevent *evl = NULL;
2126 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002127 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002129 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 if (self->kqfd < 0)
2132 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002133
Tal Einat6dc57e22018-06-30 23:02:48 +03002134 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 PyErr_Format(PyExc_ValueError,
2136 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002137 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 return NULL;
2139 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002140
Tal Einat6dc57e22018-06-30 23:02:48 +03002141 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 ptimeoutspec = NULL;
2143 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002144 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002145 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002146 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002147 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002148 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002149 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002150 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002151 return NULL;
2152 }
2153
Victor Stinner4448c082015-03-31 11:48:34 +02002154 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002155 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002156
Victor Stinner4448c082015-03-31 11:48:34 +02002157 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 PyErr_SetString(PyExc_ValueError,
2159 "timeout must be positive or None");
2160 return NULL;
2161 }
Victor Stinner4448c082015-03-31 11:48:34 +02002162 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002164
Tal Einat6dc57e22018-06-30 23:02:48 +03002165 if (changelist != Py_None) {
2166 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002167 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 return NULL;
2169 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002170 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2171 PyErr_SetString(PyExc_OverflowError,
2172 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 goto error;
2174 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002175 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 chl = PyMem_New(struct kevent, nchanges);
2178 if (chl == NULL) {
2179 PyErr_NoMemory();
2180 goto error;
2181 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002182 for (i = 0; i < nchanges; ++i) {
2183 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 PyErr_SetString(PyExc_TypeError,
2186 "changelist must be an iterable of "
2187 "select.kevent objects");
2188 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002190 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002192 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002196 if (maxevents) {
2197 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 if (evl == NULL) {
2199 PyErr_NoMemory();
2200 goto error;
2201 }
2202 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002203
Victor Stinner4448c082015-03-31 11:48:34 +02002204 if (ptimeoutspec)
2205 deadline = _PyTime_GetMonotonicClock() + timeout;
2206
2207 do {
2208 Py_BEGIN_ALLOW_THREADS
2209 errno = 0;
2210 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002211 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002212 Py_END_ALLOW_THREADS
2213
2214 if (errno != EINTR)
2215 break;
2216
2217 /* kevent() was interrupted by a signal */
2218 if (PyErr_CheckSignals())
2219 goto error;
2220
2221 if (ptimeoutspec) {
2222 timeout = deadline - _PyTime_GetMonotonicClock();
2223 if (timeout < 0) {
2224 gotevents = 0;
2225 break;
2226 }
2227 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2228 goto error;
2229 /* retry kevent() with the recomputed timeout */
2230 }
2231 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 if (gotevents == -1) {
2234 PyErr_SetFromErrno(PyExc_OSError);
2235 goto error;
2236 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 result = PyList_New(gotevents);
2239 if (result == NULL) {
2240 goto error;
2241 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 for (i = 0; i < gotevents; i++) {
2244 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002245
Dino Viehlandf9190542019-09-14 15:20:27 +01002246 ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 if (ch == NULL) {
2248 goto error;
2249 }
2250 ch->e = evl[i];
2251 PyList_SET_ITEM(result, i, (PyObject *)ch);
2252 }
2253 PyMem_Free(chl);
2254 PyMem_Free(evl);
2255 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002256
2257 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 PyMem_Free(chl);
2259 PyMem_Free(evl);
2260 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002261 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002263}
2264
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002265static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 {"closed", (getter)kqueue_queue_get_closed, NULL,
2267 "True if the kqueue handler is closed"},
2268 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002269};
2270
Tal Einat6dc57e22018-06-30 23:02:48 +03002271#endif /* HAVE_KQUEUE */
2272
2273
2274/* ************************************************************************ */
2275
2276#include "clinic/selectmodule.c.h"
2277
2278#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2279
2280static PyMethodDef poll_methods[] = {
2281 SELECT_POLL_REGISTER_METHODDEF
2282 SELECT_POLL_MODIFY_METHODDEF
2283 SELECT_POLL_UNREGISTER_METHODDEF
2284 SELECT_POLL_POLL_METHODDEF
2285 {NULL, NULL} /* sentinel */
2286};
2287
Dino Viehlandf9190542019-09-14 15:20:27 +01002288
2289static PyType_Slot poll_Type_slots[] = {
2290 {Py_tp_dealloc, poll_dealloc},
2291 {Py_tp_methods, poll_methods},
2292 {Py_tp_new, poll_new},
2293 {0, 0},
2294};
2295
2296static PyType_Spec poll_Type_spec = {
2297 "select.poll",
2298 sizeof(pollObject),
2299 0,
2300 Py_TPFLAGS_DEFAULT,
2301 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002302};
2303
2304#ifdef HAVE_SYS_DEVPOLL_H
2305
2306static PyMethodDef devpoll_methods[] = {
2307 SELECT_DEVPOLL_REGISTER_METHODDEF
2308 SELECT_DEVPOLL_MODIFY_METHODDEF
2309 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2310 SELECT_DEVPOLL_POLL_METHODDEF
2311 SELECT_DEVPOLL_CLOSE_METHODDEF
2312 SELECT_DEVPOLL_FILENO_METHODDEF
2313 {NULL, NULL} /* sentinel */
2314};
2315
Tal Einat6dc57e22018-06-30 23:02:48 +03002316#endif /* HAVE_SYS_DEVPOLL_H */
2317
2318#endif /* HAVE_POLL */
2319
2320#ifdef HAVE_EPOLL
2321
2322static PyMethodDef pyepoll_methods[] = {
2323 SELECT_EPOLL_FROMFD_METHODDEF
2324 SELECT_EPOLL_CLOSE_METHODDEF
2325 SELECT_EPOLL_FILENO_METHODDEF
2326 SELECT_EPOLL_MODIFY_METHODDEF
2327 SELECT_EPOLL_REGISTER_METHODDEF
2328 SELECT_EPOLL_UNREGISTER_METHODDEF
2329 SELECT_EPOLL_POLL_METHODDEF
2330 SELECT_EPOLL___ENTER___METHODDEF
2331 SELECT_EPOLL___EXIT___METHODDEF
2332 {NULL, NULL},
2333};
2334
Dino Viehlandf9190542019-09-14 15:20:27 +01002335static PyType_Slot pyEpoll_Type_slots[] = {
2336 {Py_tp_dealloc, pyepoll_dealloc},
2337 {Py_tp_doc, (void*)pyepoll_doc},
2338 {Py_tp_getattro, PyObject_GenericGetAttr},
2339 {Py_tp_getset, pyepoll_getsetlist},
2340 {Py_tp_methods, pyepoll_methods},
2341 {Py_tp_new, select_epoll},
2342 {0, 0},
2343};
2344
2345static PyType_Spec pyEpoll_Type_spec = {
2346 "select.epoll",
2347 sizeof(pyEpoll_Object),
2348 0,
2349 Py_TPFLAGS_DEFAULT,
2350 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002351};
2352
2353#endif /* HAVE_EPOLL */
2354
2355#ifdef HAVE_KQUEUE
2356
Tal Einat6dc57e22018-06-30 23:02:48 +03002357static PyMethodDef kqueue_queue_methods[] = {
2358 SELECT_KQUEUE_FROMFD_METHODDEF
2359 SELECT_KQUEUE_CLOSE_METHODDEF
2360 SELECT_KQUEUE_FILENO_METHODDEF
2361 SELECT_KQUEUE_CONTROL_METHODDEF
2362 {NULL, NULL},
2363};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002364
Dino Viehlandf9190542019-09-14 15:20:27 +01002365static PyType_Slot kqueue_queue_Type_slots[] = {
2366 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002367 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002368 {Py_tp_getset, kqueue_queue_getsetlist},
2369 {Py_tp_methods, kqueue_queue_methods},
2370 {Py_tp_new, select_kqueue},
2371 {0, 0},
2372};
2373
2374static PyType_Spec kqueue_queue_Type_spec = {
2375 "select.kqueue",
2376 sizeof(kqueue_queue_Object),
2377 0,
2378 Py_TPFLAGS_DEFAULT,
2379 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002380};
2381
2382#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002383
2384
2385
2386
2387
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002388/* ************************************************************************ */
2389
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002390
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002391static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002392 SELECT_SELECT_METHODDEF
2393 SELECT_POLL_METHODDEF
2394 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002396};
2397
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002398PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002399"This module supports asynchronous I/O on multiple file descriptors.\n\
2400\n\
2401*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002402On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002403
Martin v. Löwis1a214512008-06-11 05:26:20 +00002404
Dino Viehlandf9190542019-09-14 15:20:27 +01002405
2406static int
2407_select_traverse(PyObject *module, visitproc visit, void *arg)
2408{
Hai Shif707d942020-03-16 21:15:01 +08002409 Py_VISIT(get_select_state(module)->close);
2410 Py_VISIT(get_select_state(module)->poll_Type);
2411 Py_VISIT(get_select_state(module)->devpoll_Type);
2412 Py_VISIT(get_select_state(module)->pyEpoll_Type);
2413 Py_VISIT(get_select_state(module)->kqueue_event_Type);
2414 Py_VISIT(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002415 return 0;
2416}
2417
2418static int
2419_select_clear(PyObject *module)
2420{
Hai Shif707d942020-03-16 21:15:01 +08002421 Py_CLEAR(get_select_state(module)->close);
2422 Py_CLEAR(get_select_state(module)->poll_Type);
2423 Py_CLEAR(get_select_state(module)->devpoll_Type);
2424 Py_CLEAR(get_select_state(module)->pyEpoll_Type);
2425 Py_CLEAR(get_select_state(module)->kqueue_event_Type);
2426 Py_CLEAR(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002427 return 0;
2428}
2429
2430static void
2431_select_free(void *module)
2432{
2433 _select_clear((PyObject *)module);
2434}
2435
Martin v. Löwis1a214512008-06-11 05:26:20 +00002436static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 PyModuleDef_HEAD_INIT,
2438 "select",
2439 module_doc,
Dino Viehlandf9190542019-09-14 15:20:27 +01002440 sizeof(_selectstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 select_methods,
2442 NULL,
Dino Viehlandf9190542019-09-14 15:20:27 +01002443 _select_traverse,
2444 _select_clear,
2445 _select_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002446};
2447
Mark Hammond62b1ab12002-07-23 06:31:15 +00002448PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002449PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 PyObject *m;
2452 m = PyModule_Create(&selectmodule);
2453 if (m == NULL)
2454 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002455
Hai Shif707d942020-03-16 21:15:01 +08002456 get_select_state(m)->close = PyUnicode_InternFromString("close");
Dino Viehlandf9190542019-09-14 15:20:27 +01002457
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002458 Py_INCREF(PyExc_OSError);
2459 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002460
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002461#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002462#ifdef HAVE_BROKEN_PIPE_BUF
2463#undef PIPE_BUF
2464#define PIPE_BUF 512
2465#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002466 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002467#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002468
Charles-François Natali986a56c2013-01-19 12:19:10 +01002469#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002470#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 if (select_have_broken_poll()) {
2472 if (PyObject_DelAttrString(m, "poll") == -1) {
2473 PyErr_Clear();
2474 }
2475 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002476#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002478#endif
Dino Viehlandf9190542019-09-14 15:20:27 +01002479 PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
2480 if (poll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002482 get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002483 Py_INCREF(poll_Type);
2484
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002485 PyModule_AddIntMacro(m, POLLIN);
2486 PyModule_AddIntMacro(m, POLLPRI);
2487 PyModule_AddIntMacro(m, POLLOUT);
2488 PyModule_AddIntMacro(m, POLLERR);
2489 PyModule_AddIntMacro(m, POLLHUP);
2490 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002491
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002492#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002493 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002494#endif
2495#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002496 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002497#endif
2498#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002499 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002500#endif
2501#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002502 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002503#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002504#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002505 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002506#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002507#ifdef POLLRDHUP
2508 /* Kernel 2.6.17+ */
2509 PyModule_AddIntMacro(m, POLLRDHUP);
2510#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002512#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002513
Jesus Cead8b9ae62011-11-14 19:07:41 +01002514#ifdef HAVE_SYS_DEVPOLL_H
Dino Viehlandf9190542019-09-14 15:20:27 +01002515 PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
2516 if (devpoll_Type == NULL)
Jesus Cead8b9ae62011-11-14 19:07:41 +01002517 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002518 get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002519 Py_INCREF(devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01002520#endif
2521
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002522#ifdef HAVE_EPOLL
Dino Viehlandf9190542019-09-14 15:20:27 +01002523 PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
2524 if (pyEpoll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002526 get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002527 Py_INCREF(pyEpoll_Type);
Hai Shif707d942020-03-16 21:15:01 +08002528 PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002529
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002530 PyModule_AddIntMacro(m, EPOLLIN);
2531 PyModule_AddIntMacro(m, EPOLLOUT);
2532 PyModule_AddIntMacro(m, EPOLLPRI);
2533 PyModule_AddIntMacro(m, EPOLLERR);
2534 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002535#ifdef EPOLLRDHUP
2536 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002537 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002538#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002539 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002540#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002542 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002543#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002544#ifdef EPOLLEXCLUSIVE
2545 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2546#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002547
2548#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002549 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002550#endif
2551#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002552 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002553#endif
2554#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002555 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002556#endif
2557#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002558 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002559#endif
2560#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002561 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002562#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002563
Benjamin Peterson95c16622011-12-27 15:36:32 -06002564#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002565 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002566#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002567#endif /* HAVE_EPOLL */
2568
2569#ifdef HAVE_KQUEUE
Dino Viehlandf9190542019-09-14 15:20:27 +01002570 PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
2571 if (kqueue_event_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002573 get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
2574 Py_INCREF(get_select_state(m)->kqueue_event_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002575 PyModule_AddObject(m, "kevent", kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002576
Dino Viehlandf9190542019-09-14 15:20:27 +01002577 PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
2578 if (kqueue_queue_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002580 get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
2581 Py_INCREF(get_select_state(m)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002582 PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583
2584 /* event filters */
2585 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2586 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002589#endif
2590#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002592#endif
2593#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002595#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002598#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002599#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002601#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 /* event flags */
2605 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2606 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2607 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2608 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2609 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2610 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002611
Berker Peksag7ec64562016-09-14 18:16:59 +03002612#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002614#endif
2615#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002617#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2620 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002623#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002625#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002628#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2630 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2631 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2632 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2633 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2634 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2635 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002636#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002638 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002639#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2641 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2642 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2643 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2644 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2647 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2648 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002649#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650
2651 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002652#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2654 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2655 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002656#endif
2657
2658#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002660}