blob: fb71e9196f32a0b4c9f60d73dbf149452c39859d [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
Miss Islington (bot)500cd89e2020-05-26 06:38:18 -0700242The first three arguments are iterables of file descriptors to be waited for:
Tal Einat6dc57e22018-06-30 23:02:48 +0300243rlist -- 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)
Miss Islington (bot)500cd89e2020-05-26 06:38:18 -0700267/*[clinic end generated code: output=2b3cfa824f7ae4cf input=e467f5d68033de00]*/
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
Miss Islington (bot)500cd89e2020-05-26 06:38:18 -0700323 /* Convert iterables to fd_sets, and get maximum fd number
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 * 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
Anthony Sottile48fc35a2020-06-23 15:19:46 -0700461 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.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)
Anthony Sottile48fc35a2020-06-23 15:19:46 -0700470/*[clinic end generated code: output=0dc7173c800a4a65 input=34e16cfb28d3c900]*/
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
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300767static PyMethodDef devpoll_methods[];
768
Jesus Cead8b9ae62011-11-14 19:07:41 +0100769typedef struct {
770 PyObject_HEAD
771 int fd_devpoll;
772 int max_n_fds;
773 int n_fds;
774 struct pollfd *fds;
775} devpollObject;
776
Victor Stinner13423c32013-08-22 00:19:50 +0200777static PyObject *
778devpoll_err_closed(void)
779{
780 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
781 return NULL;
782}
783
Jesus Cead8b9ae62011-11-14 19:07:41 +0100784static int devpoll_flush(devpollObject *self)
785{
786 int size, n;
787
788 if (!self->n_fds) return 0;
789
790 size = sizeof(struct pollfd)*self->n_fds;
791 self->n_fds = 0;
792
Victor Stinner54799672015-03-19 23:33:09 +0100793 n = _Py_write(self->fd_devpoll, self->fds, size);
794 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100795 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100796
Jesus Cead8b9ae62011-11-14 19:07:41 +0100797 if (n < size) {
798 /*
799 ** Data writed to /dev/poll is a binary data structure. It is not
800 ** clear what to do if a partial write occurred. For now, raise
801 ** an exception and see if we actually found this problem in
802 ** the wild.
803 ** See http://bugs.python.org/issue6397.
804 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300805 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100806 "Please, report at http://bugs.python.org/. "
807 "Data to report: Size tried: %d, actual size written: %d.",
808 size, n);
809 return -1;
810 }
811 return 0;
812}
813
814static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300815internal_devpoll_register(devpollObject *self, int fd,
816 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100817{
Victor Stinner13423c32013-08-22 00:19:50 +0200818 if (self->fd_devpoll < 0)
819 return devpoll_err_closed();
820
Jesus Cead8b9ae62011-11-14 19:07:41 +0100821 if (remove) {
822 self->fds[self->n_fds].fd = fd;
823 self->fds[self->n_fds].events = POLLREMOVE;
824
825 if (++self->n_fds == self->max_n_fds) {
826 if (devpoll_flush(self))
827 return NULL;
828 }
829 }
830
831 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200832 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100833
834 if (++self->n_fds == self->max_n_fds) {
835 if (devpoll_flush(self))
836 return NULL;
837 }
838
839 Py_RETURN_NONE;
840}
841
Tal Einat6dc57e22018-06-30 23:02:48 +0300842/*[clinic input]
843select.devpoll.register
844
845 fd: fildes
846 either an integer, or an object with a fileno() method returning
847 an int
Anthony Sottile48fc35a2020-06-23 15:19:46 -0700848 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300849 an optional bitmask describing the type of events to check for
850 /
851
852Register a file descriptor with the polling object.
853[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100854
855static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300856select_devpoll_register_impl(devpollObject *self, int fd,
857 unsigned short eventmask)
Anthony Sottile48fc35a2020-06-23 15:19:46 -0700858/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859{
Tal Einat6dc57e22018-06-30 23:02:48 +0300860 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100861}
862
Tal Einat6dc57e22018-06-30 23:02:48 +0300863/*[clinic input]
864select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100865
Tal Einat6dc57e22018-06-30 23:02:48 +0300866 fd: fildes
867 either an integer, or an object with a fileno() method returning
868 an int
Anthony Sottile48fc35a2020-06-23 15:19:46 -0700869 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300870 an optional bitmask describing the type of events to check for
871 /
872
873Modify a possible already registered file descriptor.
874[clinic start generated code]*/
875
876static PyObject *
877select_devpoll_modify_impl(devpollObject *self, int fd,
878 unsigned short eventmask)
Anthony Sottile48fc35a2020-06-23 15:19:46 -0700879/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100880{
Tal Einat6dc57e22018-06-30 23:02:48 +0300881 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100882}
883
Tal Einat6dc57e22018-06-30 23:02:48 +0300884/*[clinic input]
885select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100886
Tal Einat6dc57e22018-06-30 23:02:48 +0300887 fd: fildes
888 /
889
890Remove a file descriptor being tracked by the polling object.
891[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100892
893static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300894select_devpoll_unregister_impl(devpollObject *self, int fd)
895/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100896{
Victor Stinner13423c32013-08-22 00:19:50 +0200897 if (self->fd_devpoll < 0)
898 return devpoll_err_closed();
899
Jesus Cead8b9ae62011-11-14 19:07:41 +0100900 self->fds[self->n_fds].fd = fd;
901 self->fds[self->n_fds].events = POLLREMOVE;
902
903 if (++self->n_fds == self->max_n_fds) {
904 if (devpoll_flush(self))
905 return NULL;
906 }
907
908 Py_RETURN_NONE;
909}
910
Tal Einat6dc57e22018-06-30 23:02:48 +0300911/*[clinic input]
912select.devpoll.poll
913 timeout as timeout_obj: object = None
914 /
915
916Polls the set of registered file descriptors.
917
918Returns a list containing any descriptors that have events or errors to
919report, as a list of (fd, event) 2-tuples.
920[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100921
922static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300923select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
924/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100925{
926 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200927 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100929 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200930 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100931
Victor Stinner13423c32013-08-22 00:19:50 +0200932 if (self->fd_devpoll < 0)
933 return devpoll_err_closed();
934
Jesus Cead8b9ae62011-11-14 19:07:41 +0100935 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300936 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100937 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200938 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100939 }
940 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200941 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100942 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200943 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
944 PyErr_SetString(PyExc_TypeError,
945 "timeout must be an integer or None");
946 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100947 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200948 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100949
Pablo Galindo2c15b292017-10-17 15:14:41 +0100950 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200951 if (ms < -1 || ms > INT_MAX) {
952 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
953 return NULL;
954 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100955 }
956
957 if (devpoll_flush(self))
958 return NULL;
959
960 dvp.dp_fds = self->fds;
961 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200962 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100963
Victor Stinner45ca48b2015-03-31 12:10:33 +0200964 if (timeout >= 0)
965 deadline = _PyTime_GetMonotonicClock() + timeout;
966
967 do {
968 /* call devpoll() */
969 Py_BEGIN_ALLOW_THREADS
970 errno = 0;
971 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
972 Py_END_ALLOW_THREADS
973
974 if (errno != EINTR)
975 break;
976
977 /* devpoll() was interrupted by a signal */
978 if (PyErr_CheckSignals())
979 return NULL;
980
981 if (timeout >= 0) {
982 timeout = deadline - _PyTime_GetMonotonicClock();
983 if (timeout < 0) {
984 poll_result = 0;
985 break;
986 }
987 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
988 dvp.dp_timeout = (int)ms;
989 /* retry devpoll() with the recomputed timeout */
990 }
991 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100992
993 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300994 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100995 return NULL;
996 }
997
998 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100999 result_list = PyList_New(poll_result);
1000 if (!result_list)
1001 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +02001002
1003 for (i = 0; i < poll_result; i++) {
1004 num1 = PyLong_FromLong(self->fds[i].fd);
1005 num2 = PyLong_FromLong(self->fds[i].revents);
1006 if ((num1 == NULL) || (num2 == NULL)) {
1007 Py_XDECREF(num1);
1008 Py_XDECREF(num2);
1009 goto error;
1010 }
1011 value = PyTuple_Pack(2, num1, num2);
1012 Py_DECREF(num1);
1013 Py_DECREF(num2);
1014 if (value == NULL)
1015 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001016 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001017 }
1018
1019 return result_list;
1020
1021 error:
1022 Py_DECREF(result_list);
1023 return NULL;
1024}
1025
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001026static int
1027devpoll_internal_close(devpollObject *self)
1028{
1029 int save_errno = 0;
1030 if (self->fd_devpoll >= 0) {
1031 int fd = self->fd_devpoll;
1032 self->fd_devpoll = -1;
1033 Py_BEGIN_ALLOW_THREADS
1034 if (close(fd) < 0)
1035 save_errno = errno;
1036 Py_END_ALLOW_THREADS
1037 }
1038 return save_errno;
1039}
1040
Tal Einat6dc57e22018-06-30 23:02:48 +03001041/*[clinic input]
1042select.devpoll.close
1043
1044Close the devpoll file descriptor.
1045
1046Further operations on the devpoll object will raise an exception.
1047[clinic start generated code]*/
1048
1049static PyObject *
1050select_devpoll_close_impl(devpollObject *self)
1051/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001052{
1053 errno = devpoll_internal_close(self);
1054 if (errno < 0) {
1055 PyErr_SetFromErrno(PyExc_OSError);
1056 return NULL;
1057 }
1058 Py_RETURN_NONE;
1059}
1060
Victor Stinner13423c32013-08-22 00:19:50 +02001061static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001062devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001063{
1064 if (self->fd_devpoll < 0)
1065 Py_RETURN_TRUE;
1066 else
1067 Py_RETURN_FALSE;
1068}
1069
Tal Einat6dc57e22018-06-30 23:02:48 +03001070/*[clinic input]
1071select.devpoll.fileno
1072
1073Return the file descriptor.
1074[clinic start generated code]*/
1075
1076static PyObject *
1077select_devpoll_fileno_impl(devpollObject *self)
1078/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001079{
1080 if (self->fd_devpoll < 0)
1081 return devpoll_err_closed();
1082 return PyLong_FromLong(self->fd_devpoll);
1083}
1084
Victor Stinner13423c32013-08-22 00:19:50 +02001085static PyGetSetDef devpoll_getsetlist[] = {
1086 {"closed", (getter)devpoll_get_closed, NULL,
1087 "True if the devpoll object is closed"},
1088 {0},
1089};
1090
Jesus Cead8b9ae62011-11-14 19:07:41 +01001091static devpollObject *
1092newDevPollObject(void)
1093{
1094 devpollObject *self;
1095 int fd_devpoll, limit_result;
1096 struct pollfd *fds;
1097 struct rlimit limit;
1098
Jesus Cead8b9ae62011-11-14 19:07:41 +01001099 /*
1100 ** If we try to process more that getrlimit()
1101 ** fds, the kernel will give an error, so
1102 ** we set the limit here. It is a dynamic
1103 ** value, because we can change rlimit() anytime.
1104 */
1105 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001106 if (limit_result == -1) {
1107 PyErr_SetFromErrno(PyExc_OSError);
1108 return NULL;
1109 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001110
1111 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1112 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001113 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001114
1115 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1116 if (fds == NULL) {
1117 close(fd_devpoll);
1118 PyErr_NoMemory();
1119 return NULL;
1120 }
1121
Dino Viehlandf9190542019-09-14 15:20:27 +01001122 self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001123 if (self == NULL) {
1124 close(fd_devpoll);
1125 PyMem_DEL(fds);
1126 return NULL;
1127 }
1128 self->fd_devpoll = fd_devpoll;
1129 self->max_n_fds = limit.rlim_cur;
1130 self->n_fds = 0;
1131 self->fds = fds;
1132
1133 return self;
1134}
1135
Dino Viehlandf9190542019-09-14 15:20:27 +01001136static PyObject *
1137devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1138{
1139 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1140 return NULL;
1141}
1142
Jesus Cead8b9ae62011-11-14 19:07:41 +01001143static void
1144devpoll_dealloc(devpollObject *self)
1145{
Dino Viehlandf9190542019-09-14 15:20:27 +01001146 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001147 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001148 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001149 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001150 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001151}
1152
Dino Viehlandf9190542019-09-14 15:20:27 +01001153static PyType_Slot devpoll_Type_slots[] = {
1154 {Py_tp_dealloc, devpoll_dealloc},
1155 {Py_tp_getset, devpoll_getsetlist},
1156 {Py_tp_methods, devpoll_methods},
1157 {Py_tp_new, devpoll_new},
1158 {0, 0},
1159};
1160
1161static PyType_Spec devpoll_Type_spec = {
1162 "select.devpoll",
1163 sizeof(devpollObject),
1164 0,
1165 Py_TPFLAGS_DEFAULT,
1166 devpoll_Type_slots
1167};
1168
Jesus Cead8b9ae62011-11-14 19:07:41 +01001169#endif /* HAVE_SYS_DEVPOLL_H */
1170
1171
Tal Einat6dc57e22018-06-30 23:02:48 +03001172/*[clinic input]
1173select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001174
Tal Einat6dc57e22018-06-30 23:02:48 +03001175Returns a polling object.
1176
1177This object supports registering and unregistering file descriptors, and then
1178polling them for I/O events.
1179[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001180
1181static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001182select_poll_impl(PyObject *module)
1183/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001186}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187
Jesus Cead8b9ae62011-11-14 19:07:41 +01001188#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001189
1190/*[clinic input]
1191select.devpoll
1192
1193Returns a polling object.
1194
1195This object supports registering and unregistering file descriptors, and then
1196polling them for I/O events.
1197[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001198
1199static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001200select_devpoll_impl(PyObject *module)
1201/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001202{
1203 return (PyObject *)newDevPollObject();
1204}
1205#endif
1206
1207
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001210 * On some systems poll() sets errno on invalid file descriptors. We test
1211 * for this at runtime because this bug may be fixed or introduced between
1212 * OS releases.
1213 */
1214static int select_have_broken_poll(void)
1215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 int poll_test;
1217 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 /* Create a file descriptor to make invalid */
1222 if (pipe(filedes) < 0) {
1223 return 1;
1224 }
1225 poll_struct.fd = filedes[0];
1226 close(filedes[0]);
1227 close(filedes[1]);
1228 poll_test = poll(&poll_struct, 1, 0);
1229 if (poll_test < 0) {
1230 return 1;
1231 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1232 return 1;
1233 }
1234 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001235}
1236#endif /* __APPLE__ */
1237
1238#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001239
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001240#ifdef HAVE_EPOLL
1241/* **************************************************************************
1242 * epoll interface for Linux 2.6
1243 *
1244 * Written by Christian Heimes
1245 * Inspired by Twisted's _epoll.pyx and select.poll()
1246 */
1247
1248#ifdef HAVE_SYS_EPOLL_H
1249#include <sys/epoll.h>
1250#endif
1251
1252typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001254 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001255} pyEpoll_Object;
1256
Dino Viehlandf9190542019-09-14 15:20:27 +01001257#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258
1259static PyObject *
1260pyepoll_err_closed(void)
1261{
Victor Stinner13423c32013-08-22 00:19:50 +02001262 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001264}
1265
1266static int
1267pyepoll_internal_close(pyEpoll_Object *self)
1268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 int save_errno = 0;
1270 if (self->epfd >= 0) {
1271 int epfd = self->epfd;
1272 self->epfd = -1;
1273 Py_BEGIN_ALLOW_THREADS
1274 if (close(epfd) < 0)
1275 save_errno = errno;
1276 Py_END_ALLOW_THREADS
1277 }
1278 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001279}
1280
1281static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001282newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001285 assert(type != NULL);
1286 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1287 assert(epoll_alloc != NULL);
1288 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 if (self == NULL)
1290 return NULL;
1291
1292 if (fd == -1) {
1293 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001294#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001295 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1296#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001297 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001298#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 Py_END_ALLOW_THREADS
1300 }
1301 else {
1302 self->epfd = fd;
1303 }
1304 if (self->epfd < 0) {
1305 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001306 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 return NULL;
1308 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001309
1310#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001311 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001312 Py_DECREF(self);
1313 return NULL;
1314 }
1315#endif
1316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001318}
1319
1320
Tal Einat6dc57e22018-06-30 23:02:48 +03001321/*[clinic input]
1322@classmethod
1323select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001324
Tal Einat6dc57e22018-06-30 23:02:48 +03001325 sizehint: int = -1
1326 The expected number of events to be registered. It must be positive,
1327 or -1 to use the default. It is only used on older systems where
1328 epoll_create1() is not available; otherwise it has no effect (though its
1329 value is still checked).
1330 flags: int = 0
1331 Deprecated and completely ignored. However, when supplied, its value
1332 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1333
1334Returns an epolling object.
1335[clinic start generated code]*/
1336
1337static PyObject *
1338select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1339/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1340{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001341 if (sizehint == -1) {
1342 sizehint = FD_SETSIZE - 1;
1343 }
1344 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001345 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001346 return NULL;
1347 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001348
1349#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001350 if (flags && flags != EPOLL_CLOEXEC) {
1351 PyErr_SetString(PyExc_OSError, "invalid flags");
1352 return NULL;
1353 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001354#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001355
Berker Peksage2197d12016-09-26 23:30:41 +03001356 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357}
1358
1359
1360static void
1361pyepoll_dealloc(pyEpoll_Object *self)
1362{
Dino Viehlandf9190542019-09-14 15:20:27 +01001363 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001365 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1366 epoll_free((PyObject *)self);
1367 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368}
1369
Tal Einat6dc57e22018-06-30 23:02:48 +03001370/*[clinic input]
1371select.epoll.close
1372
1373Close the epoll control file descriptor.
1374
1375Further operations on the epoll object will raise an exception.
1376[clinic start generated code]*/
1377
1378static PyObject *
1379select_epoll_close_impl(pyEpoll_Object *self)
1380/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 errno = pyepoll_internal_close(self);
1383 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001384 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 return NULL;
1386 }
1387 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388}
1389
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
1391static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001392pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 if (self->epfd < 0)
1395 Py_RETURN_TRUE;
1396 else
1397 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001398}
1399
Tal Einat6dc57e22018-06-30 23:02:48 +03001400/*[clinic input]
1401select.epoll.fileno
1402
1403Return the epoll control file descriptor.
1404[clinic start generated code]*/
1405
1406static PyObject *
1407select_epoll_fileno_impl(pyEpoll_Object *self)
1408/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 if (self->epfd < 0)
1411 return pyepoll_err_closed();
1412 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001413}
1414
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001415
Tal Einat6dc57e22018-06-30 23:02:48 +03001416/*[clinic input]
1417@classmethod
1418select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001419
Tal Einat6dc57e22018-06-30 23:02:48 +03001420 fd: int
1421 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422
Tal Einat6dc57e22018-06-30 23:02:48 +03001423Create an epoll object from a given control fd.
1424[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425
1426static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001427select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1428/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1429{
1430 SOCKET s_fd = (SOCKET)fd;
1431 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1432}
1433
1434
1435static PyObject *
1436pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 struct epoll_event ev;
1439 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 if (epfd < 0)
1442 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001443
Guido van Rossumee07b942013-12-06 17:46:22 -08001444 switch (op) {
1445 case EPOLL_CTL_ADD:
1446 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 ev.events = events;
1448 ev.data.fd = fd;
1449 Py_BEGIN_ALLOW_THREADS
1450 result = epoll_ctl(epfd, op, fd, &ev);
1451 Py_END_ALLOW_THREADS
1452 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001453 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1455 * operation required a non-NULL pointer in event, even
1456 * though this argument is ignored. */
1457 Py_BEGIN_ALLOW_THREADS
1458 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 Py_END_ALLOW_THREADS
1460 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001461 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 result = -1;
1463 errno = EINVAL;
1464 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001467 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 return NULL;
1469 }
1470 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471}
1472
Tal Einat6dc57e22018-06-30 23:02:48 +03001473/*[clinic input]
1474select.epoll.register
1475
1476 fd: fildes
1477 the target file descriptor of the operation
Anthony Sottile48fc35a2020-06-23 15:19:46 -07001478 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001479 a bit set composed of the various EPOLL constants
1480
1481Registers a new fd or raises an OSError if the fd is already registered.
1482
1483The epoll interface supports all file descriptors that support poll.
1484[clinic start generated code]*/
1485
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001486static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001487select_epoll_register_impl(pyEpoll_Object *self, int fd,
1488 unsigned int eventmask)
Anthony Sottile48fc35a2020-06-23 15:19:46 -07001489/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001490{
Tal Einat6dc57e22018-06-30 23:02:48 +03001491 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001492}
1493
Tal Einat6dc57e22018-06-30 23:02:48 +03001494/*[clinic input]
1495select.epoll.modify
1496
1497 fd: fildes
1498 the target file descriptor of the operation
1499 eventmask: unsigned_int(bitwise=True)
1500 a bit set composed of the various EPOLL constants
1501
1502Modify event mask for a registered file descriptor.
1503[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001504
1505static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001506select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1507 unsigned int eventmask)
1508/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509{
Tal Einat6dc57e22018-06-30 23:02:48 +03001510 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511}
1512
Tal Einat6dc57e22018-06-30 23:02:48 +03001513/*[clinic input]
1514select.epoll.unregister
1515
1516 fd: fildes
1517 the target file descriptor of the operation
1518
1519Remove a registered file descriptor from the epoll object.
1520[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001521
1522static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001523select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1524/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001525{
Tal Einat6dc57e22018-06-30 23:02:48 +03001526 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001527}
1528
Tal Einat6dc57e22018-06-30 23:02:48 +03001529/*[clinic input]
1530select.epoll.poll
1531
1532 timeout as timeout_obj: object = None
1533 the maximum time to wait in seconds (as float);
1534 a timeout of None or -1 makes poll wait indefinitely
1535 maxevents: int = -1
1536 the maximum number of events returned; -1 means no limit
1537
1538Wait for events on the epoll file descriptor.
1539
1540Returns a list containing any descriptors that have events to report,
1541as a list of (fd, events) 2-tuples.
1542[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001543
1544static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001545select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1546 int maxevents)
1547/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 int nfds, i;
1550 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001551 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001552 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 if (self->epfd < 0)
1555 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001556
Berker Peksagb690b9b2018-09-11 20:29:48 +03001557 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001558 /* epoll_wait() has a resolution of 1 millisecond, round towards
1559 infinity to wait at least timeout seconds. */
1560 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001561 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001562 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1563 PyErr_SetString(PyExc_TypeError,
1564 "timeout must be an integer or None");
1565 }
1566 return NULL;
1567 }
1568
1569 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1570 if (ms < INT_MIN || ms > INT_MAX) {
1571 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1572 return NULL;
1573 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001574 /* epoll_wait(2) treats all arbitrary negative numbers the same
1575 for the timeout argument, but -1 is the documented way to block
1576 indefinitely in the epoll_wait(2) documentation, so we set ms
1577 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001578
Berker Peksagb690b9b2018-09-11 20:29:48 +03001579 Note that we didn't use INFTIM here since it's non-standard and
1580 isn't available under Linux. */
1581 if (ms < 0) {
1582 ms = -1;
1583 }
1584
1585 if (timeout >= 0) {
1586 deadline = _PyTime_GetMonotonicClock() + timeout;
1587 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001591 maxevents = FD_SETSIZE-1;
1592 }
1593 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 PyErr_Format(PyExc_ValueError,
1595 "maxevents must be greater than 0, got %d",
1596 maxevents);
1597 return NULL;
1598 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001599
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001600 evs = PyMem_New(struct epoll_event, maxevents);
1601 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001602 PyErr_NoMemory();
1603 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605
Victor Stinner41eba222015-03-30 21:59:21 +02001606 do {
1607 Py_BEGIN_ALLOW_THREADS
1608 errno = 0;
1609 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1610 Py_END_ALLOW_THREADS
1611
1612 if (errno != EINTR)
1613 break;
1614
1615 /* poll() was interrupted by a signal */
1616 if (PyErr_CheckSignals())
1617 goto error;
1618
1619 if (timeout >= 0) {
1620 timeout = deadline - _PyTime_GetMonotonicClock();
1621 if (timeout < 0) {
1622 nfds = 0;
1623 break;
1624 }
1625 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1626 /* retry epoll_wait() with the recomputed timeout */
1627 }
1628 } while(1);
1629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001631 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 goto error;
1633 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 elist = PyList_New(nfds);
1636 if (elist == NULL) {
1637 goto error;
1638 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001641 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 if (etuple == NULL) {
1643 Py_CLEAR(elist);
1644 goto error;
1645 }
1646 PyList_SET_ITEM(elist, i, etuple);
1647 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001648
Christian Heimesf6cd9672008-03-26 13:45:42 +00001649 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001650 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652}
1653
Tal Einat6dc57e22018-06-30 23:02:48 +03001654
1655/*[clinic input]
1656select.epoll.__enter__
1657
1658[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001659
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001660static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001661select_epoll___enter___impl(pyEpoll_Object *self)
1662/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001663{
1664 if (self->epfd < 0)
1665 return pyepoll_err_closed();
1666
1667 Py_INCREF(self);
1668 return (PyObject *)self;
1669}
1670
Tal Einat6dc57e22018-06-30 23:02:48 +03001671/*[clinic input]
1672select.epoll.__exit__
1673
1674 exc_type: object = None
1675 exc_value: object = None
1676 exc_tb: object = None
1677 /
1678
1679[clinic start generated code]*/
1680
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001681static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001682select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1683 PyObject *exc_value, PyObject *exc_tb)
1684/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001685{
Dino Viehlandf9190542019-09-14 15:20:27 +01001686 return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001687}
1688
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001689static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 {"closed", (getter)pyepoll_get_closed, NULL,
1691 "True if the epoll handler is closed"},
1692 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001693};
1694
Dino Viehlandf9190542019-09-14 15:20:27 +01001695PyDoc_STRVAR(pyepoll_doc,
1696"select.epoll(sizehint=-1, flags=0)\n\
1697\n\
1698Returns an epolling object\n\
1699\n\
1700sizehint must be a positive integer or -1 for the default size. The\n\
1701sizehint is used to optimize internal data structures. It doesn't limit\n\
1702the maximum number of monitored events.");
1703
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001704#endif /* HAVE_EPOLL */
1705
1706#ifdef HAVE_KQUEUE
1707/* **************************************************************************
1708 * kqueue interface for BSD
1709 *
1710 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1711 * All rights reserved.
1712 *
1713 * Redistribution and use in source and binary forms, with or without
1714 * modification, are permitted provided that the following conditions
1715 * are met:
1716 * 1. Redistributions of source code must retain the above copyright
1717 * notice, this list of conditions and the following disclaimer.
1718 * 2. Redistributions in binary form must reproduce the above copyright
1719 * notice, this list of conditions and the following disclaimer in the
1720 * documentation and/or other materials provided with the distribution.
1721 *
1722 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1723 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1724 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1725 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1726 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1727 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1728 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1729 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1730 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1731 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1732 * SUCH DAMAGE.
1733 */
1734
1735#ifdef HAVE_SYS_EVENT_H
1736#include <sys/event.h>
1737#endif
1738
1739PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001740"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741\n\
1742This object is the equivalent of the struct kevent for the C API.\n\
1743\n\
1744See the kqueue manpage for more detailed information about the meaning\n\
1745of the arguments.\n\
1746\n\
1747One minor note: while you might hope that udata could store a\n\
1748reference to a python object, it cannot, because it is impossible to\n\
1749keep a proper reference count of the object once it's passed into the\n\
1750kernel. Therefore, I have restricted it to only storing an integer. I\n\
1751recommend ignoring it and simply using the 'ident' field to key off\n\
1752of. You could also set up a dictionary on the python side to store a\n\
1753udata->object mapping.");
1754
1755typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyObject_HEAD
1757 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001758} kqueue_event_Object;
1759
Dino Viehlandf9190542019-09-14 15:20:27 +01001760#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001761
1762typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 PyObject_HEAD
1764 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001765} kqueue_queue_Object;
1766
Dino Viehlandf9190542019-09-14 15:20:27 +01001767#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001768
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001769#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1770# error uintptr_t does not match void *!
1771#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1772# define T_UINTPTRT T_ULONGLONG
1773# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001774# define UINTPTRT_FMT_UNIT "K"
1775# define INTPTRT_FMT_UNIT "L"
1776#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1777# define T_UINTPTRT T_ULONG
1778# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001779# define UINTPTRT_FMT_UNIT "k"
1780# define INTPTRT_FMT_UNIT "l"
1781#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1782# define T_UINTPTRT T_UINT
1783# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001784# define UINTPTRT_FMT_UNIT "I"
1785# define INTPTRT_FMT_UNIT "i"
1786#else
1787# error uintptr_t does not match int, long, or long long!
1788#endif
1789
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001790#if SIZEOF_LONG_LONG == 8
1791# define T_INT64 T_LONGLONG
1792# define INT64_FMT_UNIT "L"
1793#elif SIZEOF_LONG == 8
1794# define T_INT64 T_LONG
1795# define INT64_FMT_UNIT "l"
1796#elif SIZEOF_INT == 8
1797# define T_INT64 T_INT
1798# define INT64_FMT_UNIT "i"
1799#else
1800# define INT64_FMT_UNIT "_"
1801#endif
1802
1803#if SIZEOF_LONG_LONG == 4
1804# define T_UINT32 T_ULONGLONG
1805# define UINT32_FMT_UNIT "K"
1806#elif SIZEOF_LONG == 4
1807# define T_UINT32 T_ULONG
1808# define UINT32_FMT_UNIT "k"
1809#elif SIZEOF_INT == 4
1810# define T_UINT32 T_UINT
1811# define UINT32_FMT_UNIT "I"
1812#else
1813# define UINT32_FMT_UNIT "_"
1814#endif
1815
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001816/*
1817 * kevent is not standard and its members vary across BSDs.
1818 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001819#ifdef __NetBSD__
1820# define FILTER_TYPE T_UINT32
1821# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1822# define FLAGS_TYPE T_UINT32
1823# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1824# define FFLAGS_TYPE T_UINT32
1825# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001826#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001827# define FILTER_TYPE T_SHORT
1828# define FILTER_FMT_UNIT "h"
1829# define FLAGS_TYPE T_USHORT
1830# define FLAGS_FMT_UNIT "H"
1831# define FFLAGS_TYPE T_UINT
1832# define FFLAGS_FMT_UNIT "I"
1833#endif
1834
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001835#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001836# define DATA_TYPE T_INT64
1837# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001838#else
1839# define DATA_TYPE T_INTPTRT
1840# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001841#endif
1842
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001843/* Unfortunately, we can't store python objects in udata, because
1844 * kevents in the kernel can be removed without warning, which would
1845 * forever lose the refcount on the object stored with it.
1846 */
1847
1848#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1849static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001850 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1851 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1852 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001854 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1856 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857};
1858#undef KQ_OFF
1859
1860static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001861
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001862kqueue_event_repr(kqueue_event_Object *s)
1863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 char buf[1024];
1865 PyOS_snprintf(
1866 buf, sizeof(buf),
1867 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001868 "data=0x%llx udata=%p>",
1869 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1870 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001872}
1873
1874static int
1875kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1876{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 PyObject *pfd;
1878 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1879 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001880 static const char fmt[] = "O|"
1881 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1882 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1887 &pfd, &(self->e.filter), &(self->e.flags),
1888 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1889 return -1;
1890 }
1891
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001892 if (PyLong_Check(pfd)) {
1893 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 }
1895 else {
1896 self->e.ident = PyObject_AsFileDescriptor(pfd);
1897 }
1898 if (PyErr_Occurred()) {
1899 return -1;
1900 }
1901 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001902}
1903
1904static PyObject *
1905kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001907{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001908 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001911 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001913
1914#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1915 result = CMP(s->e.ident, o->e.ident)
1916 : CMP(s->e.filter, o->e.filter)
1917 : CMP(s->e.flags, o->e.flags)
1918 : CMP(s->e.fflags, o->e.fflags)
1919 : CMP(s->e.data, o->e.data)
1920 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1921 : 0;
1922#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001923
stratakise8b19652017-11-02 11:32:54 +01001924 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001925}
1926
Dino Viehlandf9190542019-09-14 15:20:27 +01001927static PyType_Slot kqueue_event_Type_slots[] = {
1928 {Py_tp_doc, (void*)kqueue_event_doc},
1929 {Py_tp_init, kqueue_event_init},
1930 {Py_tp_members, kqueue_event_members},
1931 {Py_tp_new, PyType_GenericNew},
1932 {Py_tp_repr, kqueue_event_repr},
1933 {Py_tp_richcompare, kqueue_event_richcompare},
1934 {0, 0},
1935};
1936
1937static PyType_Spec kqueue_event_Type_spec = {
1938 "select.kevent",
1939 sizeof(kqueue_event_Object),
1940 0,
1941 Py_TPFLAGS_DEFAULT,
1942 kqueue_event_Type_slots
1943};
1944
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001945static PyObject *
1946kqueue_queue_err_closed(void)
1947{
Victor Stinner13423c32013-08-22 00:19:50 +02001948 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001950}
1951
1952static int
1953kqueue_queue_internal_close(kqueue_queue_Object *self)
1954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 int save_errno = 0;
1956 if (self->kqfd >= 0) {
1957 int kqfd = self->kqfd;
1958 self->kqfd = -1;
1959 Py_BEGIN_ALLOW_THREADS
1960 if (close(kqfd) < 0)
1961 save_errno = errno;
1962 Py_END_ALLOW_THREADS
1963 }
1964 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001965}
1966
1967static PyObject *
1968newKqueue_Object(PyTypeObject *type, SOCKET fd)
1969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001971 assert(type != NULL);
1972 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1973 assert(queue_alloc != NULL);
1974 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 if (self == NULL) {
1976 return NULL;
1977 }
1978
1979 if (fd == -1) {
1980 Py_BEGIN_ALLOW_THREADS
1981 self->kqfd = kqueue();
1982 Py_END_ALLOW_THREADS
1983 }
1984 else {
1985 self->kqfd = fd;
1986 }
1987 if (self->kqfd < 0) {
1988 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001989 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 return NULL;
1991 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001992
1993 if (fd == -1) {
1994 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1995 Py_DECREF(self);
1996 return NULL;
1997 }
1998 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002000}
2001
Tal Einat6dc57e22018-06-30 23:02:48 +03002002/*[clinic input]
2003@classmethod
2004select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002005
Tal Einat6dc57e22018-06-30 23:02:48 +03002006Kqueue syscall wrapper.
2007
2008For example, to start watching a socket for input:
2009>>> kq = kqueue()
2010>>> sock = socket()
2011>>> sock.connect((host, port))
2012>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
2013
2014To wait one second for it to become writeable:
2015>>> kq.control(None, 1, 1000)
2016
2017To stop listening:
2018>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2019[clinic start generated code]*/
2020
2021static PyObject *
2022select_kqueue_impl(PyTypeObject *type)
2023/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002026}
2027
2028static void
2029kqueue_queue_dealloc(kqueue_queue_Object *self)
2030{
Dino Viehlandf9190542019-09-14 15:20:27 +01002031 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002033 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2034 kqueue_free((PyObject *)self);
2035 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002036}
2037
Tal Einat6dc57e22018-06-30 23:02:48 +03002038/*[clinic input]
2039select.kqueue.close
2040
2041Close the kqueue control file descriptor.
2042
2043Further operations on the kqueue object will raise an exception.
2044[clinic start generated code]*/
2045
2046static PyObject *
2047select_kqueue_close_impl(kqueue_queue_Object *self)
2048/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002049{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 errno = kqueue_queue_internal_close(self);
2051 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002052 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 return NULL;
2054 }
2055 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002056}
2057
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002058static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002059kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 if (self->kqfd < 0)
2062 Py_RETURN_TRUE;
2063 else
2064 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002065}
2066
Tal Einat6dc57e22018-06-30 23:02:48 +03002067/*[clinic input]
2068select.kqueue.fileno
2069
2070Return the kqueue control file descriptor.
2071[clinic start generated code]*/
2072
2073static PyObject *
2074select_kqueue_fileno_impl(kqueue_queue_Object *self)
2075/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 if (self->kqfd < 0)
2078 return kqueue_queue_err_closed();
2079 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002080}
2081
Tal Einat6dc57e22018-06-30 23:02:48 +03002082/*[clinic input]
2083@classmethod
2084select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002085
Tal Einat6dc57e22018-06-30 23:02:48 +03002086 fd: int
2087 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002088
Tal Einat6dc57e22018-06-30 23:02:48 +03002089Create a kqueue object from a given control fd.
2090[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002091
2092static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002093select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2094/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002095{
Tal Einat6dc57e22018-06-30 23:02:48 +03002096 SOCKET s_fd = (SOCKET)fd;
2097
2098 return newKqueue_Object(type, s_fd);
2099}
2100
2101/*[clinic input]
2102select.kqueue.control
2103
2104 changelist: object
2105 Must be an iterable of kevent objects describing the changes to be made
2106 to the kernel's watch list or None.
2107 maxevents: int
2108 The maximum number of events that the kernel will return.
2109 timeout as otimeout: object = None
2110 The maximum time to wait in seconds, or else None to wait forever.
2111 This accepts floats for smaller timeouts, too.
2112 /
2113
2114Calls the kernel kevent function.
2115[clinic start generated code]*/
2116
2117static PyObject *
2118select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2119 int maxevents, PyObject *otimeout)
2120/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 int gotevents = 0;
2123 int nchanges = 0;
2124 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002125 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 PyObject *result = NULL;
2127 struct kevent *evl = NULL;
2128 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002129 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002131 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (self->kqfd < 0)
2134 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002135
Tal Einat6dc57e22018-06-30 23:02:48 +03002136 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 PyErr_Format(PyExc_ValueError,
2138 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002139 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 return NULL;
2141 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002142
Tal Einat6dc57e22018-06-30 23:02:48 +03002143 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 ptimeoutspec = NULL;
2145 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002146 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002147 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002148 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002149 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002150 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002151 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002152 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002153 return NULL;
2154 }
2155
Victor Stinner4448c082015-03-31 11:48:34 +02002156 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002157 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002158
Victor Stinner4448c082015-03-31 11:48:34 +02002159 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 PyErr_SetString(PyExc_ValueError,
2161 "timeout must be positive or None");
2162 return NULL;
2163 }
Victor Stinner4448c082015-03-31 11:48:34 +02002164 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002166
Tal Einat6dc57e22018-06-30 23:02:48 +03002167 if (changelist != Py_None) {
2168 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002169 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 return NULL;
2171 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002172 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2173 PyErr_SetString(PyExc_OverflowError,
2174 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 goto error;
2176 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002177 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 chl = PyMem_New(struct kevent, nchanges);
2180 if (chl == NULL) {
2181 PyErr_NoMemory();
2182 goto error;
2183 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002184 for (i = 0; i < nchanges; ++i) {
2185 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 PyErr_SetString(PyExc_TypeError,
2188 "changelist must be an iterable of "
2189 "select.kevent objects");
2190 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002192 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002194 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002198 if (maxevents) {
2199 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 if (evl == NULL) {
2201 PyErr_NoMemory();
2202 goto error;
2203 }
2204 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002205
Victor Stinner4448c082015-03-31 11:48:34 +02002206 if (ptimeoutspec)
2207 deadline = _PyTime_GetMonotonicClock() + timeout;
2208
2209 do {
2210 Py_BEGIN_ALLOW_THREADS
2211 errno = 0;
2212 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002213 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002214 Py_END_ALLOW_THREADS
2215
2216 if (errno != EINTR)
2217 break;
2218
2219 /* kevent() was interrupted by a signal */
2220 if (PyErr_CheckSignals())
2221 goto error;
2222
2223 if (ptimeoutspec) {
2224 timeout = deadline - _PyTime_GetMonotonicClock();
2225 if (timeout < 0) {
2226 gotevents = 0;
2227 break;
2228 }
2229 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2230 goto error;
2231 /* retry kevent() with the recomputed timeout */
2232 }
2233 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 if (gotevents == -1) {
2236 PyErr_SetFromErrno(PyExc_OSError);
2237 goto error;
2238 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 result = PyList_New(gotevents);
2241 if (result == NULL) {
2242 goto error;
2243 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 for (i = 0; i < gotevents; i++) {
2246 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002247
Dino Viehlandf9190542019-09-14 15:20:27 +01002248 ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 if (ch == NULL) {
2250 goto error;
2251 }
2252 ch->e = evl[i];
2253 PyList_SET_ITEM(result, i, (PyObject *)ch);
2254 }
2255 PyMem_Free(chl);
2256 PyMem_Free(evl);
2257 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002258
2259 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 PyMem_Free(chl);
2261 PyMem_Free(evl);
2262 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002263 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002265}
2266
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002267static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 {"closed", (getter)kqueue_queue_get_closed, NULL,
2269 "True if the kqueue handler is closed"},
2270 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002271};
2272
Tal Einat6dc57e22018-06-30 23:02:48 +03002273#endif /* HAVE_KQUEUE */
2274
2275
2276/* ************************************************************************ */
2277
2278#include "clinic/selectmodule.c.h"
2279
2280#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2281
2282static PyMethodDef poll_methods[] = {
2283 SELECT_POLL_REGISTER_METHODDEF
2284 SELECT_POLL_MODIFY_METHODDEF
2285 SELECT_POLL_UNREGISTER_METHODDEF
2286 SELECT_POLL_POLL_METHODDEF
2287 {NULL, NULL} /* sentinel */
2288};
2289
Dino Viehlandf9190542019-09-14 15:20:27 +01002290
2291static PyType_Slot poll_Type_slots[] = {
2292 {Py_tp_dealloc, poll_dealloc},
2293 {Py_tp_methods, poll_methods},
2294 {Py_tp_new, poll_new},
2295 {0, 0},
2296};
2297
2298static PyType_Spec poll_Type_spec = {
2299 "select.poll",
2300 sizeof(pollObject),
2301 0,
2302 Py_TPFLAGS_DEFAULT,
2303 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002304};
2305
2306#ifdef HAVE_SYS_DEVPOLL_H
2307
2308static PyMethodDef devpoll_methods[] = {
2309 SELECT_DEVPOLL_REGISTER_METHODDEF
2310 SELECT_DEVPOLL_MODIFY_METHODDEF
2311 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2312 SELECT_DEVPOLL_POLL_METHODDEF
2313 SELECT_DEVPOLL_CLOSE_METHODDEF
2314 SELECT_DEVPOLL_FILENO_METHODDEF
2315 {NULL, NULL} /* sentinel */
2316};
2317
Tal Einat6dc57e22018-06-30 23:02:48 +03002318#endif /* HAVE_SYS_DEVPOLL_H */
2319
2320#endif /* HAVE_POLL */
2321
2322#ifdef HAVE_EPOLL
2323
2324static PyMethodDef pyepoll_methods[] = {
2325 SELECT_EPOLL_FROMFD_METHODDEF
2326 SELECT_EPOLL_CLOSE_METHODDEF
2327 SELECT_EPOLL_FILENO_METHODDEF
2328 SELECT_EPOLL_MODIFY_METHODDEF
2329 SELECT_EPOLL_REGISTER_METHODDEF
2330 SELECT_EPOLL_UNREGISTER_METHODDEF
2331 SELECT_EPOLL_POLL_METHODDEF
2332 SELECT_EPOLL___ENTER___METHODDEF
2333 SELECT_EPOLL___EXIT___METHODDEF
2334 {NULL, NULL},
2335};
2336
Dino Viehlandf9190542019-09-14 15:20:27 +01002337static PyType_Slot pyEpoll_Type_slots[] = {
2338 {Py_tp_dealloc, pyepoll_dealloc},
2339 {Py_tp_doc, (void*)pyepoll_doc},
2340 {Py_tp_getattro, PyObject_GenericGetAttr},
2341 {Py_tp_getset, pyepoll_getsetlist},
2342 {Py_tp_methods, pyepoll_methods},
2343 {Py_tp_new, select_epoll},
2344 {0, 0},
2345};
2346
2347static PyType_Spec pyEpoll_Type_spec = {
2348 "select.epoll",
2349 sizeof(pyEpoll_Object),
2350 0,
2351 Py_TPFLAGS_DEFAULT,
2352 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002353};
2354
2355#endif /* HAVE_EPOLL */
2356
2357#ifdef HAVE_KQUEUE
2358
Tal Einat6dc57e22018-06-30 23:02:48 +03002359static PyMethodDef kqueue_queue_methods[] = {
2360 SELECT_KQUEUE_FROMFD_METHODDEF
2361 SELECT_KQUEUE_CLOSE_METHODDEF
2362 SELECT_KQUEUE_FILENO_METHODDEF
2363 SELECT_KQUEUE_CONTROL_METHODDEF
2364 {NULL, NULL},
2365};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002366
Dino Viehlandf9190542019-09-14 15:20:27 +01002367static PyType_Slot kqueue_queue_Type_slots[] = {
2368 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002369 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002370 {Py_tp_getset, kqueue_queue_getsetlist},
2371 {Py_tp_methods, kqueue_queue_methods},
2372 {Py_tp_new, select_kqueue},
2373 {0, 0},
2374};
2375
2376static PyType_Spec kqueue_queue_Type_spec = {
2377 "select.kqueue",
2378 sizeof(kqueue_queue_Object),
2379 0,
2380 Py_TPFLAGS_DEFAULT,
2381 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002382};
2383
2384#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002385
2386
2387
2388
2389
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002390/* ************************************************************************ */
2391
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002392
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002393static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002394 SELECT_SELECT_METHODDEF
2395 SELECT_POLL_METHODDEF
2396 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002398};
2399
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002400PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002401"This module supports asynchronous I/O on multiple file descriptors.\n\
2402\n\
2403*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002404On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002405
Martin v. Löwis1a214512008-06-11 05:26:20 +00002406
Dino Viehlandf9190542019-09-14 15:20:27 +01002407
2408static int
2409_select_traverse(PyObject *module, visitproc visit, void *arg)
2410{
Hai Shif707d942020-03-16 21:15:01 +08002411 Py_VISIT(get_select_state(module)->close);
2412 Py_VISIT(get_select_state(module)->poll_Type);
2413 Py_VISIT(get_select_state(module)->devpoll_Type);
2414 Py_VISIT(get_select_state(module)->pyEpoll_Type);
2415 Py_VISIT(get_select_state(module)->kqueue_event_Type);
2416 Py_VISIT(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002417 return 0;
2418}
2419
2420static int
2421_select_clear(PyObject *module)
2422{
Hai Shif707d942020-03-16 21:15:01 +08002423 Py_CLEAR(get_select_state(module)->close);
2424 Py_CLEAR(get_select_state(module)->poll_Type);
2425 Py_CLEAR(get_select_state(module)->devpoll_Type);
2426 Py_CLEAR(get_select_state(module)->pyEpoll_Type);
2427 Py_CLEAR(get_select_state(module)->kqueue_event_Type);
2428 Py_CLEAR(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002429 return 0;
2430}
2431
2432static void
2433_select_free(void *module)
2434{
2435 _select_clear((PyObject *)module);
2436}
2437
Martin v. Löwis1a214512008-06-11 05:26:20 +00002438static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 PyModuleDef_HEAD_INIT,
2440 "select",
2441 module_doc,
Dino Viehlandf9190542019-09-14 15:20:27 +01002442 sizeof(_selectstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 select_methods,
2444 NULL,
Dino Viehlandf9190542019-09-14 15:20:27 +01002445 _select_traverse,
2446 _select_clear,
2447 _select_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002448};
2449
Mark Hammond62b1ab12002-07-23 06:31:15 +00002450PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002451PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 PyObject *m;
2454 m = PyModule_Create(&selectmodule);
2455 if (m == NULL)
2456 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002457
Hai Shif707d942020-03-16 21:15:01 +08002458 get_select_state(m)->close = PyUnicode_InternFromString("close");
Dino Viehlandf9190542019-09-14 15:20:27 +01002459
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002460 Py_INCREF(PyExc_OSError);
2461 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002462
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002463#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002464#ifdef HAVE_BROKEN_PIPE_BUF
2465#undef PIPE_BUF
2466#define PIPE_BUF 512
2467#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002468 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002469#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002470
Charles-François Natali986a56c2013-01-19 12:19:10 +01002471#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002472#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 if (select_have_broken_poll()) {
2474 if (PyObject_DelAttrString(m, "poll") == -1) {
2475 PyErr_Clear();
2476 }
2477 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002478#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002480#endif
Dino Viehlandf9190542019-09-14 15:20:27 +01002481 PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
2482 if (poll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002484 get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002485 Py_INCREF(poll_Type);
2486
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002487 PyModule_AddIntMacro(m, POLLIN);
2488 PyModule_AddIntMacro(m, POLLPRI);
2489 PyModule_AddIntMacro(m, POLLOUT);
2490 PyModule_AddIntMacro(m, POLLERR);
2491 PyModule_AddIntMacro(m, POLLHUP);
2492 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002493
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002494#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002495 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002496#endif
2497#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002498 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002499#endif
2500#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002501 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002502#endif
2503#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002504 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002505#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002506#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002507 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002508#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002509#ifdef POLLRDHUP
2510 /* Kernel 2.6.17+ */
2511 PyModule_AddIntMacro(m, POLLRDHUP);
2512#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002514#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002515
Jesus Cead8b9ae62011-11-14 19:07:41 +01002516#ifdef HAVE_SYS_DEVPOLL_H
Dino Viehlandf9190542019-09-14 15:20:27 +01002517 PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
2518 if (devpoll_Type == NULL)
Jesus Cead8b9ae62011-11-14 19:07:41 +01002519 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002520 get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002521 Py_INCREF(devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01002522#endif
2523
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002524#ifdef HAVE_EPOLL
Dino Viehlandf9190542019-09-14 15:20:27 +01002525 PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
2526 if (pyEpoll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002528 get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002529 Py_INCREF(pyEpoll_Type);
Hai Shif707d942020-03-16 21:15:01 +08002530 PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002531
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002532 PyModule_AddIntMacro(m, EPOLLIN);
2533 PyModule_AddIntMacro(m, EPOLLOUT);
2534 PyModule_AddIntMacro(m, EPOLLPRI);
2535 PyModule_AddIntMacro(m, EPOLLERR);
2536 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002537#ifdef EPOLLRDHUP
2538 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002539 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002540#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002541 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002542#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002543 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002544 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002545#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002546#ifdef EPOLLEXCLUSIVE
2547 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2548#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002549
2550#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002551 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002552#endif
2553#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002554 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002555#endif
2556#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002557 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002558#endif
2559#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002560 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002561#endif
2562#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002563 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002564#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002565
Benjamin Peterson95c16622011-12-27 15:36:32 -06002566#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002567 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002568#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002569#endif /* HAVE_EPOLL */
2570
2571#ifdef HAVE_KQUEUE
Dino Viehlandf9190542019-09-14 15:20:27 +01002572 PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
2573 if (kqueue_event_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002575 get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
2576 Py_INCREF(get_select_state(m)->kqueue_event_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002577 PyModule_AddObject(m, "kevent", kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002578
Dino Viehlandf9190542019-09-14 15:20:27 +01002579 PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
2580 if (kqueue_queue_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002582 get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
2583 Py_INCREF(get_select_state(m)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002584 PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585
2586 /* event filters */
2587 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2588 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002589#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002591#endif
2592#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002594#endif
2595#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002596 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002597#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002598#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002600#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002601#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002603#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 /* event flags */
2607 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2608 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2609 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2610 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2611 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2612 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002613
Berker Peksag7ec64562016-09-14 18:16:59 +03002614#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002616#endif
2617#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002619#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2622 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002625#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002626 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002627#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002630#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2632 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2633 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2634 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2635 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2636 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2637 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002638#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002641#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2643 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2644 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2645 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2646 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002648 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2649 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2650 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002651#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652
2653 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002654#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2656 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2657 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002658#endif
2659
2660#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002662}