blob: 5038c325faa4eb77e0cd3be867aa15a394935338 [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
Christian Heimesea97eba2020-11-21 20:29:26 +010080#define _selectstate_by_type(type) get_select_state(PyType_GetModule(type))
Dino Viehlandf9190542019-09-14 15:20:27 +010081
Tal Einat6dc57e22018-06-30 23:02:48 +030082/*[clinic input]
83module select
Christian Heimesea97eba2020-11-21 20:29:26 +010084class select.poll "pollObject *" "_selectstate_by_type(type)->poll_Type"
85class select.devpoll "devpollObject *" "_selectstate_by_type(type)->devpoll_Type"
86class select.epoll "pyEpoll_Object *" "_selectstate_by_type(type)->pyEpoll_Type"
87class select.kqueue "kqueue_queue_Object *" "_selectstate_by_type(type)->kqueue_queue_Type"
Tal Einat6dc57e22018-06-30 23:02:48 +030088[clinic start generated code]*/
Christian Heimesea97eba2020-11-21 20:29:26 +010089/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8072de35824aa327]*/
Tal Einat6dc57e22018-06-30 23:02:48 +030090
Barry Warsawc1cb3601996-12-12 22:16:21 +000091/* list of Python objects and their file descriptor */
92typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyObject *obj; /* owned reference */
94 SOCKET fd;
95 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000096} pylist;
97
Barry Warsawc1cb3601996-12-12 22:16:21 +000098static void
Tim Peters4b046c22001-08-16 21:59:46 +000099reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +0000100{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200101 unsigned int i;
102 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200103 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 }
105 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000106}
107
108
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000109/* returns -1 and sets the Python exception if an error occurred, otherwise
110 returns a number >= 0
111*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000112static int
Brett Cannon62dba4c2003-09-10 19:37:42 +0000113seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200116 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100117 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 PyObject* fast_seq = NULL;
119 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +0000120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
122 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Benjamin Petersone0edb8b2010-06-27 23:49:45 +0000124 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 if (!fast_seq)
126 return -1;
127
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100128 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 SOCKET v;
130
131 /* any intervening fileno() calls could decr this refcnt */
132 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200133 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 Py_INCREF(o);
136 v = PyObject_AsFileDescriptor( o );
137 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000138
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000139#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000141#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200142 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 PyErr_SetString(PyExc_ValueError,
144 "filedescriptor out of range in select()");
145 goto finally;
146 }
147 if (v > max)
148 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000149#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200153 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 PyErr_SetString(PyExc_ValueError,
155 "too many file descriptors in select()");
156 goto finally;
157 }
158 fd2obj[index].obj = o;
159 fd2obj[index].fd = v;
160 fd2obj[index].sentinel = 0;
161 fd2obj[++index].sentinel = -1;
162 }
163 Py_DECREF(fast_seq);
164 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000165
166 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 Py_XDECREF(o);
168 Py_DECREF(fast_seq);
169 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000170}
171
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000172/* returns NULL and sets the Python exception if an error occurred */
173static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000174set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 int i, j, count=0;
177 PyObject *list, *o;
178 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
181 if (FD_ISSET(fd2obj[j].fd, set))
182 count++;
183 }
184 list = PyList_New(count);
185 if (!list)
186 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 i = 0;
189 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
190 fd = fd2obj[j].fd;
191 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 o = fd2obj[j].obj;
193 fd2obj[j].obj = NULL;
194 /* transfer ownership */
195 if (PyList_SetItem(list, i, o) < 0)
196 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 i++;
199 }
200 }
201 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000202 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 Py_DECREF(list);
204 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000205}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000206
Barry Warsawb44740f2001-08-16 16:52:59 +0000207#undef SELECT_USES_HEAP
208#if FD_SETSIZE > 1024
209#define SELECT_USES_HEAP
210#endif /* FD_SETSIZE > 1024 */
211
Tal Einat6dc57e22018-06-30 23:02:48 +0300212/*[clinic input]
213select.select
214
215 rlist: object
216 wlist: object
217 xlist: object
218 timeout as timeout_obj: object = None
219 /
220
221Wait until one or more file descriptors are ready for some kind of I/O.
222
Jakub Stasiak372ee272020-05-25 09:03:48 +0200223The first three arguments are iterables of file descriptors to be waited for:
Tal Einat6dc57e22018-06-30 23:02:48 +0300224rlist -- wait until ready for reading
225wlist -- wait until ready for writing
226xlist -- wait for an "exceptional condition"
227If only one kind of condition is required, pass [] for the other lists.
228
229A file descriptor is either a socket or file object, or a small integer
230gotten from a fileno() method call on one of those.
231
232The optional 4th argument specifies a timeout in seconds; it may be
233a floating point number to specify fractions of seconds. If it is absent
234or None, the call will never time out.
235
236The return value is a tuple of three lists corresponding to the first three
237arguments; each contains the subset of the corresponding file descriptors
238that are ready.
239
240*** IMPORTANT NOTICE ***
241On Windows, only sockets are supported; on Unix, all file
242descriptors can be used.
243[clinic start generated code]*/
244
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000245static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300246select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
247 PyObject *xlist, PyObject *timeout_obj)
Jakub Stasiak372ee272020-05-25 09:03:48 +0200248/*[clinic end generated code: output=2b3cfa824f7ae4cf input=e467f5d68033de00]*/
Guido van Rossumed233a51992-06-23 09:07:03 +0000249{
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000252#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 /* XXX: All this should probably be implemented as follows:
254 * - find the highest descriptor we're interested in
255 * - add one
256 * - that's the size
257 * See: Stevens, APitUE, $12.5.1
258 */
259 pylist rfd2obj[FD_SETSIZE + 1];
260 pylist wfd2obj[FD_SETSIZE + 1];
261 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000262#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 PyObject *ret = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 int imax, omax, emax, max;
267 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200268 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000269
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200270 if (timeout_obj == Py_None)
271 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200273 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100274 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200275 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
276 PyErr_SetString(PyExc_TypeError,
277 "timeout must be a float or None");
278 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100279 return NULL;
280 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100281
Pablo Galindo2c15b292017-10-17 15:14:41 +0100282 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100283 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100284 if (tv.tv_sec < 0) {
285 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 return NULL;
287 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 tvp = &tv;
289 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000290
Barry Warsawb44740f2001-08-16 16:52:59 +0000291#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 /* Allocate memory for the lists */
293 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
294 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
295 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
296 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +0100297 if (rfd2obj) PyMem_Free(rfd2obj);
298 if (wfd2obj) PyMem_Free(wfd2obj);
299 if (efd2obj) PyMem_Free(efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return PyErr_NoMemory();
301 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000302#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200303
Jakub Stasiak372ee272020-05-25 09:03:48 +0200304 /* Convert iterables to fd_sets, and get maximum fd number
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 * propagates the Python exception set in seq2set()
306 */
307 rfd2obj[0].sentinel = -1;
308 wfd2obj[0].sentinel = -1;
309 efd2obj[0].sentinel = -1;
Tal Einat6dc57e22018-06-30 23:02:48 +0300310 if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300312 if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300314 if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 max = imax;
318 if (omax > max) max = omax;
319 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000320
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200321 if (tvp)
322 deadline = _PyTime_GetMonotonicClock() + timeout;
323
324 do {
325 Py_BEGIN_ALLOW_THREADS
326 errno = 0;
327 n = select(max, &ifdset, &ofdset, &efdset, tvp);
328 Py_END_ALLOW_THREADS
329
330 if (errno != EINTR)
331 break;
332
333 /* select() was interrupted by a signal */
334 if (PyErr_CheckSignals())
335 goto finally;
336
337 if (tvp) {
338 timeout = deadline - _PyTime_GetMonotonicClock();
339 if (timeout < 0) {
Oran Avraham7f524152018-12-05 22:36:03 +0200340 /* bpo-35310: lists were unmodified -- clear them explicitly */
341 FD_ZERO(&ifdset);
342 FD_ZERO(&ofdset);
343 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200344 n = 0;
345 break;
346 }
347 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200348 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200349 }
350 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000351
Thomas Heller106f4c72002-09-24 16:51:00 +0000352#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200354 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000356#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200358 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000360#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 else {
362 /* any of these three calls can raise an exception. it's more
363 convenient to test for this after all three calls... but
364 is that acceptable?
365 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300366 rlist = set2list(&ifdset, rfd2obj);
367 wlist = set2list(&ofdset, wfd2obj);
368 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 if (PyErr_Occurred())
370 ret = NULL;
371 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300372 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000373
Tal Einat6dc57e22018-06-30 23:02:48 +0300374 Py_XDECREF(rlist);
375 Py_XDECREF(wlist);
376 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 }
378
Barry Warsawc1cb3601996-12-12 22:16:21 +0000379 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 reap_obj(rfd2obj);
381 reap_obj(wfd2obj);
382 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000383#ifdef SELECT_USES_HEAP
Victor Stinner00d7abd2020-12-01 09:56:42 +0100384 PyMem_Free(rfd2obj);
385 PyMem_Free(wfd2obj);
386 PyMem_Free(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000387#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000389}
390
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000391#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000393 * poll() support
394 */
395
396typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 PyObject_HEAD
398 PyObject *dict;
399 int ufd_uptodate;
400 int ufd_len;
401 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300402 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000403} pollObject;
404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406 contained within a pollObject. Return 1 on success, 0 on an error.
407*/
408
409static int
410update_ufd_array(pollObject *self)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 Py_ssize_t i, pos;
413 PyObject *key, *value;
414 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000415
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200416 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
418 if (self->ufds == NULL) {
419 self->ufds = old_ufds;
420 PyErr_NoMemory();
421 return 0;
422 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 i = pos = 0;
425 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200426 assert(i < self->ufd_len);
427 /* Never overflow */
428 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200429 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 i++;
431 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200432 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 self->ufd_uptodate = 1;
434 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Tal Einat6dc57e22018-06-30 23:02:48 +0300437/*[clinic input]
438select.poll.register
439
440 fd: fildes
441 either an integer, or an object with a fileno() method returning an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700442 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300443 an optional bitmask describing the type of events to check for
444 /
445
446Register a file descriptor with the polling object.
447[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448
449static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300450select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700451/*[clinic end generated code: output=0dc7173c800a4a65 input=34e16cfb28d3c900]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452{
Tal Einat6dc57e22018-06-30 23:02:48 +0300453 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 /* Add entry to the internal dictionary: the key is the
457 file descriptor, and the value is the event mask. */
458 key = PyLong_FromLong(fd);
459 if (key == NULL)
460 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300461 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 if (value == NULL) {
463 Py_DECREF(key);
464 return NULL;
465 }
466 err = PyDict_SetItem(self->dict, key, value);
467 Py_DECREF(key);
468 Py_DECREF(value);
469 if (err < 0)
470 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 self->ufd_uptodate = 0;
473
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200474 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475}
476
Tal Einat6dc57e22018-06-30 23:02:48 +0300477
478/*[clinic input]
479select.poll.modify
480
481 fd: fildes
482 either an integer, or an object with a fileno() method returning
483 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300484 eventmask: unsigned_short
Tal Einat6dc57e22018-06-30 23:02:48 +0300485 a bitmask describing the type of events to check for
486 /
487
488Modify an already registered file descriptor.
489[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000490
491static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300492select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300493/*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000494{
Tal Einat6dc57e22018-06-30 23:02:48 +0300495 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Modify registered fd */
499 key = PyLong_FromLong(fd);
500 if (key == NULL)
501 return NULL;
Serhiy Storchakab510e102020-10-26 12:47:57 +0200502 err = PyDict_Contains(self->dict, key);
503 if (err < 0) {
504 Py_DECREF(key);
505 return NULL;
506 }
507 if (err == 0) {
508 errno = ENOENT;
509 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200510 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return NULL;
512 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300513 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 if (value == NULL) {
515 Py_DECREF(key);
516 return NULL;
517 }
518 err = PyDict_SetItem(self->dict, key, value);
519 Py_DECREF(key);
520 Py_DECREF(value);
521 if (err < 0)
522 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 self->ufd_uptodate = 0;
525
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200526 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000527}
528
529
Tal Einat6dc57e22018-06-30 23:02:48 +0300530/*[clinic input]
531select.poll.unregister
532
533 fd: fildes
534 /
535
536Remove a file descriptor being tracked by the polling object.
537[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000538
539static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300540select_poll_unregister_impl(pollObject *self, int fd)
541/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 /* Check whether the fd is already in the array */
546 key = PyLong_FromLong(fd);
547 if (key == NULL)
548 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 if (PyDict_DelItem(self->dict, key) == -1) {
551 Py_DECREF(key);
552 /* This will simply raise the KeyError set by PyDict_DelItem
553 if the file descriptor isn't registered. */
554 return NULL;
555 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 Py_DECREF(key);
558 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000559
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200560 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000561}
562
Tal Einat6dc57e22018-06-30 23:02:48 +0300563/*[clinic input]
564select.poll.poll
565
566 timeout as timeout_obj: object = None
567 /
568
569Polls the set of registered file descriptors.
570
571Returns a list containing any descriptors that have events or errors to
572report, as a list of (fd, event) 2-tuples.
573[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000574
575static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300576select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
577/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000578{
Tal Einat6dc57e22018-06-30 23:02:48 +0300579 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200580 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200582 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584
Tal Einat6dc57e22018-06-30 23:02:48 +0300585 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200586 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100587 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200588 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
589 PyErr_SetString(PyExc_TypeError,
590 "timeout must be an integer or None");
591 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200593 }
594
Pablo Galindo2c15b292017-10-17 15:14:41 +0100595 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200596 if (ms < INT_MIN || ms > INT_MAX) {
597 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200599 }
600
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200601 if (timeout >= 0) {
602 deadline = _PyTime_GetMonotonicClock() + timeout;
603 }
604 }
605
606 /* On some OSes, typically BSD-based ones, the timeout parameter of the
607 poll() syscall, when negative, must be exactly INFTIM, where defined,
608 or -1. See issue 31334. */
609 if (ms < 0) {
610#ifdef INFTIM
611 ms = INFTIM;
612#else
613 ms = -1;
614#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000616
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300617 /* Avoid concurrent poll() invocation, issue 8865 */
618 if (self->poll_running) {
619 PyErr_SetString(PyExc_RuntimeError,
620 "concurrent poll() invocation");
621 return NULL;
622 }
623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 /* Ensure the ufd array is up to date */
625 if (!self->ufd_uptodate)
626 if (update_ufd_array(self) == 0)
627 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300629 self->poll_running = 1;
630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200632 async_err = 0;
633 do {
634 Py_BEGIN_ALLOW_THREADS
635 errno = 0;
636 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
637 Py_END_ALLOW_THREADS
638
639 if (errno != EINTR)
640 break;
641
642 /* poll() was interrupted by a signal */
643 if (PyErr_CheckSignals()) {
644 async_err = 1;
645 break;
646 }
647
648 if (timeout >= 0) {
649 timeout = deadline - _PyTime_GetMonotonicClock();
650 if (timeout < 0) {
651 poll_result = 0;
652 break;
653 }
654 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
655 /* retry poll() with the recomputed timeout */
656 }
657 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300659 self->poll_running = 0;
660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200662 if (!async_err)
663 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 return NULL;
665 }
666
667 /* build the result list */
668
669 result_list = PyList_New(poll_result);
670 if (!result_list)
671 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200673 for (i = 0, j = 0; j < poll_result; j++) {
674 /* skip to the next fired descriptor */
675 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 i++;
677 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200678 /* if we hit a NULL return, set value to NULL
679 and break out of loop; code at end will
680 clean up result_list */
681 value = PyTuple_New(2);
682 if (value == NULL)
683 goto error;
684 num = PyLong_FromLong(self->ufds[i].fd);
685 if (num == NULL) {
686 Py_DECREF(value);
687 goto error;
688 }
689 PyTuple_SET_ITEM(value, 0, num);
690
691 /* The &0xffff is a workaround for AIX. 'revents'
692 is a 16-bit short, and IBM assigned POLLNVAL
693 to be 0x8000, so the conversion to int results
694 in a negative number. See SF bug #923315. */
695 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
696 if (num == NULL) {
697 Py_DECREF(value);
698 goto error;
699 }
700 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700701 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200702 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 }
704 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000705
706 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 Py_DECREF(result_list);
708 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000709}
710
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000711static pollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +0100712newPollObject(PyObject *module)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 pollObject *self;
Christian Heimesea97eba2020-11-21 20:29:26 +0100715 self = PyObject_New(pollObject, get_select_state(module)->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 if (self == NULL)
717 return NULL;
718 /* ufd_uptodate is a Boolean, denoting whether the
719 array pointed to by ufds matches the contents of the dictionary. */
720 self->ufd_uptodate = 0;
721 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300722 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 self->dict = PyDict_New();
724 if (self->dict == NULL) {
725 Py_DECREF(self);
726 return NULL;
727 }
728 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000729}
730
731static void
732poll_dealloc(pollObject *self)
733{
Dino Viehlandf9190542019-09-14 15:20:27 +0100734 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 if (self->ufds != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100736 PyMem_Free(self->ufds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 Py_XDECREF(self->dict);
Victor Stinner32bd68c2020-12-01 10:37:39 +0100738 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100739 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000740}
741
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000742
Jesus Cead8b9ae62011-11-14 19:07:41 +0100743#ifdef HAVE_SYS_DEVPOLL_H
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300744static PyMethodDef devpoll_methods[];
745
Jesus Cead8b9ae62011-11-14 19:07:41 +0100746typedef struct {
747 PyObject_HEAD
748 int fd_devpoll;
749 int max_n_fds;
750 int n_fds;
751 struct pollfd *fds;
752} devpollObject;
753
Victor Stinner13423c32013-08-22 00:19:50 +0200754static PyObject *
755devpoll_err_closed(void)
756{
757 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
758 return NULL;
759}
760
Jesus Cead8b9ae62011-11-14 19:07:41 +0100761static int devpoll_flush(devpollObject *self)
762{
763 int size, n;
764
765 if (!self->n_fds) return 0;
766
767 size = sizeof(struct pollfd)*self->n_fds;
768 self->n_fds = 0;
769
Victor Stinner54799672015-03-19 23:33:09 +0100770 n = _Py_write(self->fd_devpoll, self->fds, size);
771 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100772 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100773
Jesus Cead8b9ae62011-11-14 19:07:41 +0100774 if (n < size) {
775 /*
776 ** Data writed to /dev/poll is a binary data structure. It is not
777 ** clear what to do if a partial write occurred. For now, raise
778 ** an exception and see if we actually found this problem in
779 ** the wild.
780 ** See http://bugs.python.org/issue6397.
781 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300782 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100783 "Please, report at http://bugs.python.org/. "
784 "Data to report: Size tried: %d, actual size written: %d.",
785 size, n);
786 return -1;
787 }
788 return 0;
789}
790
791static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300792internal_devpoll_register(devpollObject *self, int fd,
793 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100794{
Victor Stinner13423c32013-08-22 00:19:50 +0200795 if (self->fd_devpoll < 0)
796 return devpoll_err_closed();
797
Jesus Cead8b9ae62011-11-14 19:07:41 +0100798 if (remove) {
799 self->fds[self->n_fds].fd = fd;
800 self->fds[self->n_fds].events = POLLREMOVE;
801
802 if (++self->n_fds == self->max_n_fds) {
803 if (devpoll_flush(self))
804 return NULL;
805 }
806 }
807
808 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200809 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100810
811 if (++self->n_fds == self->max_n_fds) {
812 if (devpoll_flush(self))
813 return NULL;
814 }
815
816 Py_RETURN_NONE;
817}
818
Tal Einat6dc57e22018-06-30 23:02:48 +0300819/*[clinic input]
820select.devpoll.register
821
822 fd: fildes
823 either an integer, or an object with a fileno() method returning
824 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700825 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300826 an optional bitmask describing the type of events to check for
827 /
828
829Register a file descriptor with the polling object.
830[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100831
832static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300833select_devpoll_register_impl(devpollObject *self, int fd,
834 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700835/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100836{
Tal Einat6dc57e22018-06-30 23:02:48 +0300837 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100838}
839
Tal Einat6dc57e22018-06-30 23:02:48 +0300840/*[clinic input]
841select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100842
Tal Einat6dc57e22018-06-30 23:02:48 +0300843 fd: fildes
844 either an integer, or an object with a fileno() method returning
845 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700846 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300847 an optional bitmask describing the type of events to check for
848 /
849
850Modify a possible already registered file descriptor.
851[clinic start generated code]*/
852
853static PyObject *
854select_devpoll_modify_impl(devpollObject *self, int fd,
855 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700856/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100857{
Tal Einat6dc57e22018-06-30 23:02:48 +0300858 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859}
860
Tal Einat6dc57e22018-06-30 23:02:48 +0300861/*[clinic input]
862select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863
Tal Einat6dc57e22018-06-30 23:02:48 +0300864 fd: fildes
865 /
866
867Remove a file descriptor being tracked by the polling object.
868[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100869
870static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300871select_devpoll_unregister_impl(devpollObject *self, int fd)
872/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100873{
Victor Stinner13423c32013-08-22 00:19:50 +0200874 if (self->fd_devpoll < 0)
875 return devpoll_err_closed();
876
Jesus Cead8b9ae62011-11-14 19:07:41 +0100877 self->fds[self->n_fds].fd = fd;
878 self->fds[self->n_fds].events = POLLREMOVE;
879
880 if (++self->n_fds == self->max_n_fds) {
881 if (devpoll_flush(self))
882 return NULL;
883 }
884
885 Py_RETURN_NONE;
886}
887
Tal Einat6dc57e22018-06-30 23:02:48 +0300888/*[clinic input]
889select.devpoll.poll
890 timeout as timeout_obj: object = None
891 /
892
893Polls the set of registered file descriptors.
894
895Returns a list containing any descriptors that have events or errors to
896report, as a list of (fd, event) 2-tuples.
897[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100898
899static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300900select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
901/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902{
903 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200904 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100905 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100906 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200907 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100908
Victor Stinner13423c32013-08-22 00:19:50 +0200909 if (self->fd_devpoll < 0)
910 return devpoll_err_closed();
911
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300913 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100914 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200915 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100916 }
917 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200918 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100919 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200920 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
921 PyErr_SetString(PyExc_TypeError,
922 "timeout must be an integer or None");
923 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100924 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200925 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100926
Pablo Galindo2c15b292017-10-17 15:14:41 +0100927 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200928 if (ms < -1 || ms > INT_MAX) {
929 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
930 return NULL;
931 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100932 }
933
934 if (devpoll_flush(self))
935 return NULL;
936
937 dvp.dp_fds = self->fds;
938 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200939 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100940
Victor Stinner45ca48b2015-03-31 12:10:33 +0200941 if (timeout >= 0)
942 deadline = _PyTime_GetMonotonicClock() + timeout;
943
944 do {
945 /* call devpoll() */
946 Py_BEGIN_ALLOW_THREADS
947 errno = 0;
948 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
949 Py_END_ALLOW_THREADS
950
951 if (errno != EINTR)
952 break;
953
954 /* devpoll() was interrupted by a signal */
955 if (PyErr_CheckSignals())
956 return NULL;
957
958 if (timeout >= 0) {
959 timeout = deadline - _PyTime_GetMonotonicClock();
960 if (timeout < 0) {
961 poll_result = 0;
962 break;
963 }
964 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
965 dvp.dp_timeout = (int)ms;
966 /* retry devpoll() with the recomputed timeout */
967 }
968 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100969
970 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300971 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100972 return NULL;
973 }
974
975 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976 result_list = PyList_New(poll_result);
977 if (!result_list)
978 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200979
980 for (i = 0; i < poll_result; i++) {
981 num1 = PyLong_FromLong(self->fds[i].fd);
982 num2 = PyLong_FromLong(self->fds[i].revents);
983 if ((num1 == NULL) || (num2 == NULL)) {
984 Py_XDECREF(num1);
985 Py_XDECREF(num2);
986 goto error;
987 }
988 value = PyTuple_Pack(2, num1, num2);
989 Py_DECREF(num1);
990 Py_DECREF(num2);
991 if (value == NULL)
992 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -0700993 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100994 }
995
996 return result_list;
997
998 error:
999 Py_DECREF(result_list);
1000 return NULL;
1001}
1002
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001003static int
1004devpoll_internal_close(devpollObject *self)
1005{
1006 int save_errno = 0;
1007 if (self->fd_devpoll >= 0) {
1008 int fd = self->fd_devpoll;
1009 self->fd_devpoll = -1;
1010 Py_BEGIN_ALLOW_THREADS
1011 if (close(fd) < 0)
1012 save_errno = errno;
1013 Py_END_ALLOW_THREADS
1014 }
1015 return save_errno;
1016}
1017
Tal Einat6dc57e22018-06-30 23:02:48 +03001018/*[clinic input]
1019select.devpoll.close
1020
1021Close the devpoll file descriptor.
1022
1023Further operations on the devpoll object will raise an exception.
1024[clinic start generated code]*/
1025
1026static PyObject *
1027select_devpoll_close_impl(devpollObject *self)
1028/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001029{
1030 errno = devpoll_internal_close(self);
1031 if (errno < 0) {
1032 PyErr_SetFromErrno(PyExc_OSError);
1033 return NULL;
1034 }
1035 Py_RETURN_NONE;
1036}
1037
Victor Stinner13423c32013-08-22 00:19:50 +02001038static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001039devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001040{
1041 if (self->fd_devpoll < 0)
1042 Py_RETURN_TRUE;
1043 else
1044 Py_RETURN_FALSE;
1045}
1046
Tal Einat6dc57e22018-06-30 23:02:48 +03001047/*[clinic input]
1048select.devpoll.fileno
1049
1050Return the file descriptor.
1051[clinic start generated code]*/
1052
1053static PyObject *
1054select_devpoll_fileno_impl(devpollObject *self)
1055/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001056{
1057 if (self->fd_devpoll < 0)
1058 return devpoll_err_closed();
1059 return PyLong_FromLong(self->fd_devpoll);
1060}
1061
Victor Stinner13423c32013-08-22 00:19:50 +02001062static PyGetSetDef devpoll_getsetlist[] = {
1063 {"closed", (getter)devpoll_get_closed, NULL,
1064 "True if the devpoll object is closed"},
1065 {0},
1066};
1067
Jesus Cead8b9ae62011-11-14 19:07:41 +01001068static devpollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +01001069newDevPollObject(PyObject *module)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001070{
1071 devpollObject *self;
1072 int fd_devpoll, limit_result;
1073 struct pollfd *fds;
1074 struct rlimit limit;
1075
Jesus Cead8b9ae62011-11-14 19:07:41 +01001076 /*
1077 ** If we try to process more that getrlimit()
1078 ** fds, the kernel will give an error, so
1079 ** we set the limit here. It is a dynamic
1080 ** value, because we can change rlimit() anytime.
1081 */
1082 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083 if (limit_result == -1) {
1084 PyErr_SetFromErrno(PyExc_OSError);
1085 return NULL;
1086 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001087
1088 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1089 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001091
1092 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1093 if (fds == NULL) {
1094 close(fd_devpoll);
1095 PyErr_NoMemory();
1096 return NULL;
1097 }
1098
Christian Heimesea97eba2020-11-21 20:29:26 +01001099 self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001100 if (self == NULL) {
1101 close(fd_devpoll);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001102 PyMem_Free(fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001103 return NULL;
1104 }
1105 self->fd_devpoll = fd_devpoll;
1106 self->max_n_fds = limit.rlim_cur;
1107 self->n_fds = 0;
1108 self->fds = fds;
1109
1110 return self;
1111}
1112
Dino Viehlandf9190542019-09-14 15:20:27 +01001113static PyObject *
1114devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1115{
1116 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1117 return NULL;
1118}
1119
Jesus Cead8b9ae62011-11-14 19:07:41 +01001120static void
1121devpoll_dealloc(devpollObject *self)
1122{
Dino Viehlandf9190542019-09-14 15:20:27 +01001123 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001124 (void)devpoll_internal_close(self);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001125 PyMem_Free(self->fds);
Victor Stinner32bd68c2020-12-01 10:37:39 +01001126 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001127 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001128}
1129
Dino Viehlandf9190542019-09-14 15:20:27 +01001130static PyType_Slot devpoll_Type_slots[] = {
1131 {Py_tp_dealloc, devpoll_dealloc},
1132 {Py_tp_getset, devpoll_getsetlist},
1133 {Py_tp_methods, devpoll_methods},
1134 {Py_tp_new, devpoll_new},
1135 {0, 0},
1136};
1137
1138static PyType_Spec devpoll_Type_spec = {
1139 "select.devpoll",
1140 sizeof(devpollObject),
1141 0,
1142 Py_TPFLAGS_DEFAULT,
1143 devpoll_Type_slots
1144};
1145
Jesus Cead8b9ae62011-11-14 19:07:41 +01001146#endif /* HAVE_SYS_DEVPOLL_H */
1147
1148
Tal Einat6dc57e22018-06-30 23:02:48 +03001149/*[clinic input]
1150select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001151
Tal Einat6dc57e22018-06-30 23:02:48 +03001152Returns a polling object.
1153
1154This object supports registering and unregistering file descriptors, and then
1155polling them for I/O events.
1156[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001157
1158static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001159select_poll_impl(PyObject *module)
1160/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001161{
Christian Heimesea97eba2020-11-21 20:29:26 +01001162 return (PyObject *)newPollObject(module);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001163}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001164
Jesus Cead8b9ae62011-11-14 19:07:41 +01001165#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001166
1167/*[clinic input]
1168select.devpoll
1169
1170Returns a polling object.
1171
1172This object supports registering and unregistering file descriptors, and then
1173polling them for I/O events.
1174[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001175
1176static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001177select_devpoll_impl(PyObject *module)
1178/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001179{
Christian Heimesea97eba2020-11-21 20:29:26 +01001180 return (PyObject *)newDevPollObject(module);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001181}
1182#endif
1183
1184
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187 * On some systems poll() sets errno on invalid file descriptors. We test
1188 * for this at runtime because this bug may be fixed or introduced between
1189 * OS releases.
1190 */
1191static int select_have_broken_poll(void)
1192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 int poll_test;
1194 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 /* Create a file descriptor to make invalid */
1199 if (pipe(filedes) < 0) {
1200 return 1;
1201 }
1202 poll_struct.fd = filedes[0];
1203 close(filedes[0]);
1204 close(filedes[1]);
1205 poll_test = poll(&poll_struct, 1, 0);
1206 if (poll_test < 0) {
1207 return 1;
1208 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1209 return 1;
1210 }
1211 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001212}
1213#endif /* __APPLE__ */
1214
1215#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001216
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001217#ifdef HAVE_EPOLL
1218/* **************************************************************************
1219 * epoll interface for Linux 2.6
1220 *
1221 * Written by Christian Heimes
1222 * Inspired by Twisted's _epoll.pyx and select.poll()
1223 */
1224
1225#ifdef HAVE_SYS_EPOLL_H
1226#include <sys/epoll.h>
1227#endif
1228
1229typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001231 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001232} pyEpoll_Object;
1233
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001234static PyObject *
1235pyepoll_err_closed(void)
1236{
Victor Stinner13423c32013-08-22 00:19:50 +02001237 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001239}
1240
1241static int
1242pyepoll_internal_close(pyEpoll_Object *self)
1243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 int save_errno = 0;
1245 if (self->epfd >= 0) {
1246 int epfd = self->epfd;
1247 self->epfd = -1;
1248 Py_BEGIN_ALLOW_THREADS
1249 if (close(epfd) < 0)
1250 save_errno = errno;
1251 Py_END_ALLOW_THREADS
1252 }
1253 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254}
1255
1256static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001257newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001260 assert(type != NULL);
1261 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1262 assert(epoll_alloc != NULL);
1263 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 if (self == NULL)
1265 return NULL;
1266
1267 if (fd == -1) {
1268 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001269#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001270 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1271#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001272 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001273#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 Py_END_ALLOW_THREADS
1275 }
1276 else {
1277 self->epfd = fd;
1278 }
1279 if (self->epfd < 0) {
1280 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001281 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 return NULL;
1283 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001284
1285#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001286 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001287 Py_DECREF(self);
1288 return NULL;
1289 }
1290#endif
1291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001293}
1294
1295
Tal Einat6dc57e22018-06-30 23:02:48 +03001296/*[clinic input]
1297@classmethod
1298select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001299
Tal Einat6dc57e22018-06-30 23:02:48 +03001300 sizehint: int = -1
1301 The expected number of events to be registered. It must be positive,
1302 or -1 to use the default. It is only used on older systems where
1303 epoll_create1() is not available; otherwise it has no effect (though its
1304 value is still checked).
1305 flags: int = 0
1306 Deprecated and completely ignored. However, when supplied, its value
1307 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1308
1309Returns an epolling object.
1310[clinic start generated code]*/
1311
1312static PyObject *
1313select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1314/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1315{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001316 if (sizehint == -1) {
1317 sizehint = FD_SETSIZE - 1;
1318 }
1319 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001320 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001321 return NULL;
1322 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001323
1324#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001325 if (flags && flags != EPOLL_CLOEXEC) {
1326 PyErr_SetString(PyExc_OSError, "invalid flags");
1327 return NULL;
1328 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001329#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001330
Berker Peksage2197d12016-09-26 23:30:41 +03001331 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332}
1333
1334
1335static void
1336pyepoll_dealloc(pyEpoll_Object *self)
1337{
Dino Viehlandf9190542019-09-14 15:20:27 +01001338 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001340 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1341 epoll_free((PyObject *)self);
1342 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001343}
1344
Tal Einat6dc57e22018-06-30 23:02:48 +03001345/*[clinic input]
1346select.epoll.close
1347
1348Close the epoll control file descriptor.
1349
1350Further operations on the epoll object will raise an exception.
1351[clinic start generated code]*/
1352
1353static PyObject *
1354select_epoll_close_impl(pyEpoll_Object *self)
1355/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 errno = pyepoll_internal_close(self);
1358 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001359 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 return NULL;
1361 }
1362 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363}
1364
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365
1366static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001367pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 if (self->epfd < 0)
1370 Py_RETURN_TRUE;
1371 else
1372 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001373}
1374
Tal Einat6dc57e22018-06-30 23:02:48 +03001375/*[clinic input]
1376select.epoll.fileno
1377
1378Return the epoll control file descriptor.
1379[clinic start generated code]*/
1380
1381static PyObject *
1382select_epoll_fileno_impl(pyEpoll_Object *self)
1383/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 if (self->epfd < 0)
1386 return pyepoll_err_closed();
1387 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388}
1389
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
Tal Einat6dc57e22018-06-30 23:02:48 +03001391/*[clinic input]
1392@classmethod
1393select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001394
Tal Einat6dc57e22018-06-30 23:02:48 +03001395 fd: int
1396 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001397
Tal Einat6dc57e22018-06-30 23:02:48 +03001398Create an epoll object from a given control fd.
1399[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001400
1401static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001402select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1403/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1404{
1405 SOCKET s_fd = (SOCKET)fd;
1406 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1407}
1408
1409
1410static PyObject *
1411pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 struct epoll_event ev;
1414 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 if (epfd < 0)
1417 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418
Guido van Rossumee07b942013-12-06 17:46:22 -08001419 switch (op) {
1420 case EPOLL_CTL_ADD:
1421 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 ev.events = events;
1423 ev.data.fd = fd;
1424 Py_BEGIN_ALLOW_THREADS
1425 result = epoll_ctl(epfd, op, fd, &ev);
1426 Py_END_ALLOW_THREADS
1427 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001428 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1430 * operation required a non-NULL pointer in event, even
1431 * though this argument is ignored. */
1432 Py_BEGIN_ALLOW_THREADS
1433 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 Py_END_ALLOW_THREADS
1435 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001436 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 result = -1;
1438 errno = EINVAL;
1439 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001442 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 return NULL;
1444 }
1445 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446}
1447
Tal Einat6dc57e22018-06-30 23:02:48 +03001448/*[clinic input]
1449select.epoll.register
1450
1451 fd: fildes
1452 the target file descriptor of the operation
Anthony Sottiled0518012020-06-23 14:49:56 -07001453 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001454 a bit set composed of the various EPOLL constants
1455
1456Registers a new fd or raises an OSError if the fd is already registered.
1457
1458The epoll interface supports all file descriptors that support poll.
1459[clinic start generated code]*/
1460
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001462select_epoll_register_impl(pyEpoll_Object *self, int fd,
1463 unsigned int eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -07001464/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001465{
Tal Einat6dc57e22018-06-30 23:02:48 +03001466 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001467}
1468
Tal Einat6dc57e22018-06-30 23:02:48 +03001469/*[clinic input]
1470select.epoll.modify
1471
1472 fd: fildes
1473 the target file descriptor of the operation
1474 eventmask: unsigned_int(bitwise=True)
1475 a bit set composed of the various EPOLL constants
1476
1477Modify event mask for a registered file descriptor.
1478[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001479
1480static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001481select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1482 unsigned int eventmask)
1483/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484{
Tal Einat6dc57e22018-06-30 23:02:48 +03001485 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001486}
1487
Tal Einat6dc57e22018-06-30 23:02:48 +03001488/*[clinic input]
1489select.epoll.unregister
1490
1491 fd: fildes
1492 the target file descriptor of the operation
1493
1494Remove a registered file descriptor from the epoll object.
1495[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001496
1497static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001498select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1499/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001500{
Tal Einat6dc57e22018-06-30 23:02:48 +03001501 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502}
1503
Tal Einat6dc57e22018-06-30 23:02:48 +03001504/*[clinic input]
1505select.epoll.poll
1506
1507 timeout as timeout_obj: object = None
1508 the maximum time to wait in seconds (as float);
1509 a timeout of None or -1 makes poll wait indefinitely
1510 maxevents: int = -1
1511 the maximum number of events returned; -1 means no limit
1512
1513Wait for events on the epoll file descriptor.
1514
1515Returns a list containing any descriptors that have events to report,
1516as a list of (fd, events) 2-tuples.
1517[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001518
1519static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001520select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1521 int maxevents)
1522/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 int nfds, i;
1525 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001526 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001527 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 if (self->epfd < 0)
1530 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001531
Berker Peksagb690b9b2018-09-11 20:29:48 +03001532 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001533 /* epoll_wait() has a resolution of 1 millisecond, round towards
1534 infinity to wait at least timeout seconds. */
1535 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001536 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001537 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1538 PyErr_SetString(PyExc_TypeError,
1539 "timeout must be an integer or None");
1540 }
1541 return NULL;
1542 }
1543
1544 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1545 if (ms < INT_MIN || ms > INT_MAX) {
1546 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1547 return NULL;
1548 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001549 /* epoll_wait(2) treats all arbitrary negative numbers the same
1550 for the timeout argument, but -1 is the documented way to block
1551 indefinitely in the epoll_wait(2) documentation, so we set ms
1552 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001553
Berker Peksagb690b9b2018-09-11 20:29:48 +03001554 Note that we didn't use INFTIM here since it's non-standard and
1555 isn't available under Linux. */
1556 if (ms < 0) {
1557 ms = -1;
1558 }
1559
1560 if (timeout >= 0) {
1561 deadline = _PyTime_GetMonotonicClock() + timeout;
1562 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001566 maxevents = FD_SETSIZE-1;
1567 }
1568 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 PyErr_Format(PyExc_ValueError,
1570 "maxevents must be greater than 0, got %d",
1571 maxevents);
1572 return NULL;
1573 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001574
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001575 evs = PyMem_New(struct epoll_event, maxevents);
1576 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001577 PyErr_NoMemory();
1578 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001580
Victor Stinner41eba222015-03-30 21:59:21 +02001581 do {
1582 Py_BEGIN_ALLOW_THREADS
1583 errno = 0;
1584 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1585 Py_END_ALLOW_THREADS
1586
1587 if (errno != EINTR)
1588 break;
1589
1590 /* poll() was interrupted by a signal */
1591 if (PyErr_CheckSignals())
1592 goto error;
1593
1594 if (timeout >= 0) {
1595 timeout = deadline - _PyTime_GetMonotonicClock();
1596 if (timeout < 0) {
1597 nfds = 0;
1598 break;
1599 }
1600 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1601 /* retry epoll_wait() with the recomputed timeout */
1602 }
1603 } while(1);
1604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001606 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 goto error;
1608 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 elist = PyList_New(nfds);
1611 if (elist == NULL) {
1612 goto error;
1613 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001616 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 if (etuple == NULL) {
1618 Py_CLEAR(elist);
1619 goto error;
1620 }
1621 PyList_SET_ITEM(elist, i, etuple);
1622 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001623
Christian Heimesf6cd9672008-03-26 13:45:42 +00001624 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001625 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001627}
1628
Tal Einat6dc57e22018-06-30 23:02:48 +03001629
1630/*[clinic input]
1631select.epoll.__enter__
1632
1633[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001635static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001636select_epoll___enter___impl(pyEpoll_Object *self)
1637/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001638{
1639 if (self->epfd < 0)
1640 return pyepoll_err_closed();
1641
1642 Py_INCREF(self);
1643 return (PyObject *)self;
1644}
1645
Tal Einat6dc57e22018-06-30 23:02:48 +03001646/*[clinic input]
1647select.epoll.__exit__
1648
1649 exc_type: object = None
1650 exc_value: object = None
1651 exc_tb: object = None
1652 /
1653
1654[clinic start generated code]*/
1655
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001656static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001657select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1658 PyObject *exc_value, PyObject *exc_tb)
1659/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001660{
Christian Heimesea97eba2020-11-21 20:29:26 +01001661 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
1662 return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001663}
1664
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001665static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 {"closed", (getter)pyepoll_get_closed, NULL,
1667 "True if the epoll handler is closed"},
1668 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001669};
1670
Dino Viehlandf9190542019-09-14 15:20:27 +01001671PyDoc_STRVAR(pyepoll_doc,
1672"select.epoll(sizehint=-1, flags=0)\n\
1673\n\
1674Returns an epolling object\n\
1675\n\
1676sizehint must be a positive integer or -1 for the default size. The\n\
1677sizehint is used to optimize internal data structures. It doesn't limit\n\
1678the maximum number of monitored events.");
1679
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001680#endif /* HAVE_EPOLL */
1681
1682#ifdef HAVE_KQUEUE
1683/* **************************************************************************
1684 * kqueue interface for BSD
1685 *
1686 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1687 * All rights reserved.
1688 *
1689 * Redistribution and use in source and binary forms, with or without
1690 * modification, are permitted provided that the following conditions
1691 * are met:
1692 * 1. Redistributions of source code must retain the above copyright
1693 * notice, this list of conditions and the following disclaimer.
1694 * 2. Redistributions in binary form must reproduce the above copyright
1695 * notice, this list of conditions and the following disclaimer in the
1696 * documentation and/or other materials provided with the distribution.
1697 *
1698 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1699 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1700 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1701 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1702 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1703 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1704 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1705 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1706 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1707 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1708 * SUCH DAMAGE.
1709 */
1710
1711#ifdef HAVE_SYS_EVENT_H
1712#include <sys/event.h>
1713#endif
1714
1715PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001716"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001717\n\
1718This object is the equivalent of the struct kevent for the C API.\n\
1719\n\
1720See the kqueue manpage for more detailed information about the meaning\n\
1721of the arguments.\n\
1722\n\
1723One minor note: while you might hope that udata could store a\n\
1724reference to a python object, it cannot, because it is impossible to\n\
1725keep a proper reference count of the object once it's passed into the\n\
1726kernel. Therefore, I have restricted it to only storing an integer. I\n\
1727recommend ignoring it and simply using the 'ident' field to key off\n\
1728of. You could also set up a dictionary on the python side to store a\n\
1729udata->object mapping.");
1730
1731typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 PyObject_HEAD
1733 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001734} kqueue_event_Object;
1735
Christian Heimesea97eba2020-11-21 20:29:26 +01001736#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001737
1738typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 PyObject_HEAD
1740 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741} kqueue_queue_Object;
1742
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001743#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1744# error uintptr_t does not match void *!
1745#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1746# define T_UINTPTRT T_ULONGLONG
1747# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001748# define UINTPTRT_FMT_UNIT "K"
1749# define INTPTRT_FMT_UNIT "L"
1750#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1751# define T_UINTPTRT T_ULONG
1752# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001753# define UINTPTRT_FMT_UNIT "k"
1754# define INTPTRT_FMT_UNIT "l"
1755#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1756# define T_UINTPTRT T_UINT
1757# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001758# define UINTPTRT_FMT_UNIT "I"
1759# define INTPTRT_FMT_UNIT "i"
1760#else
1761# error uintptr_t does not match int, long, or long long!
1762#endif
1763
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001764#if SIZEOF_LONG_LONG == 8
1765# define T_INT64 T_LONGLONG
1766# define INT64_FMT_UNIT "L"
1767#elif SIZEOF_LONG == 8
1768# define T_INT64 T_LONG
1769# define INT64_FMT_UNIT "l"
1770#elif SIZEOF_INT == 8
1771# define T_INT64 T_INT
1772# define INT64_FMT_UNIT "i"
1773#else
1774# define INT64_FMT_UNIT "_"
1775#endif
1776
1777#if SIZEOF_LONG_LONG == 4
1778# define T_UINT32 T_ULONGLONG
1779# define UINT32_FMT_UNIT "K"
1780#elif SIZEOF_LONG == 4
1781# define T_UINT32 T_ULONG
1782# define UINT32_FMT_UNIT "k"
1783#elif SIZEOF_INT == 4
1784# define T_UINT32 T_UINT
1785# define UINT32_FMT_UNIT "I"
1786#else
1787# define UINT32_FMT_UNIT "_"
1788#endif
1789
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001790/*
1791 * kevent is not standard and its members vary across BSDs.
1792 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001793#ifdef __NetBSD__
1794# define FILTER_TYPE T_UINT32
1795# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1796# define FLAGS_TYPE T_UINT32
1797# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1798# define FFLAGS_TYPE T_UINT32
1799# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001800#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001801# define FILTER_TYPE T_SHORT
1802# define FILTER_FMT_UNIT "h"
1803# define FLAGS_TYPE T_USHORT
1804# define FLAGS_FMT_UNIT "H"
1805# define FFLAGS_TYPE T_UINT
1806# define FFLAGS_FMT_UNIT "I"
1807#endif
1808
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001809#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001810# define DATA_TYPE T_INT64
1811# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001812#else
1813# define DATA_TYPE T_INTPTRT
1814# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001815#endif
1816
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001817/* Unfortunately, we can't store python objects in udata, because
1818 * kevents in the kernel can be removed without warning, which would
1819 * forever lose the refcount on the object stored with it.
1820 */
1821
1822#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1823static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001824 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1825 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1826 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001828 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001829 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1830 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831};
1832#undef KQ_OFF
1833
1834static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001835
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001836kqueue_event_repr(kqueue_event_Object *s)
1837{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 char buf[1024];
1839 PyOS_snprintf(
1840 buf, sizeof(buf),
1841 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001842 "data=0x%llx udata=%p>",
1843 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1844 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001846}
1847
1848static int
1849kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 PyObject *pfd;
1852 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1853 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001854 static const char fmt[] = "O|"
1855 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1856 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1861 &pfd, &(self->e.filter), &(self->e.flags),
1862 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1863 return -1;
1864 }
1865
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001866 if (PyLong_Check(pfd)) {
1867 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 }
1869 else {
1870 self->e.ident = PyObject_AsFileDescriptor(pfd);
1871 }
1872 if (PyErr_Occurred()) {
1873 return -1;
1874 }
1875 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876}
1877
1878static PyObject *
1879kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001881{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001882 int result;
Christian Heimesea97eba2020-11-21 20:29:26 +01001883 _selectstate *state = _selectstate_by_type(Py_TYPE(s));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001884
Christian Heimesea97eba2020-11-21 20:29:26 +01001885 if (!kqueue_event_Check(o, state)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001886 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001888
1889#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1890 result = CMP(s->e.ident, o->e.ident)
1891 : CMP(s->e.filter, o->e.filter)
1892 : CMP(s->e.flags, o->e.flags)
1893 : CMP(s->e.fflags, o->e.fflags)
1894 : CMP(s->e.data, o->e.data)
1895 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1896 : 0;
1897#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
stratakise8b19652017-11-02 11:32:54 +01001899 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001900}
1901
Dino Viehlandf9190542019-09-14 15:20:27 +01001902static PyType_Slot kqueue_event_Type_slots[] = {
1903 {Py_tp_doc, (void*)kqueue_event_doc},
1904 {Py_tp_init, kqueue_event_init},
1905 {Py_tp_members, kqueue_event_members},
1906 {Py_tp_new, PyType_GenericNew},
1907 {Py_tp_repr, kqueue_event_repr},
1908 {Py_tp_richcompare, kqueue_event_richcompare},
1909 {0, 0},
1910};
1911
1912static PyType_Spec kqueue_event_Type_spec = {
1913 "select.kevent",
1914 sizeof(kqueue_event_Object),
1915 0,
1916 Py_TPFLAGS_DEFAULT,
1917 kqueue_event_Type_slots
1918};
1919
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001920static PyObject *
1921kqueue_queue_err_closed(void)
1922{
Victor Stinner13423c32013-08-22 00:19:50 +02001923 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001925}
1926
1927static int
1928kqueue_queue_internal_close(kqueue_queue_Object *self)
1929{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 int save_errno = 0;
1931 if (self->kqfd >= 0) {
1932 int kqfd = self->kqfd;
1933 self->kqfd = -1;
1934 Py_BEGIN_ALLOW_THREADS
1935 if (close(kqfd) < 0)
1936 save_errno = errno;
1937 Py_END_ALLOW_THREADS
1938 }
1939 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001940}
1941
1942static PyObject *
1943newKqueue_Object(PyTypeObject *type, SOCKET fd)
1944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001946 assert(type != NULL);
1947 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1948 assert(queue_alloc != NULL);
1949 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 if (self == NULL) {
1951 return NULL;
1952 }
1953
1954 if (fd == -1) {
1955 Py_BEGIN_ALLOW_THREADS
1956 self->kqfd = kqueue();
1957 Py_END_ALLOW_THREADS
1958 }
1959 else {
1960 self->kqfd = fd;
1961 }
1962 if (self->kqfd < 0) {
1963 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001964 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 return NULL;
1966 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001967
1968 if (fd == -1) {
1969 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1970 Py_DECREF(self);
1971 return NULL;
1972 }
1973 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001975}
1976
Tal Einat6dc57e22018-06-30 23:02:48 +03001977/*[clinic input]
1978@classmethod
1979select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001980
Tal Einat6dc57e22018-06-30 23:02:48 +03001981Kqueue syscall wrapper.
1982
1983For example, to start watching a socket for input:
1984>>> kq = kqueue()
1985>>> sock = socket()
1986>>> sock.connect((host, port))
1987>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1988
1989To wait one second for it to become writeable:
1990>>> kq.control(None, 1, 1000)
1991
1992To stop listening:
1993>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1994[clinic start generated code]*/
1995
1996static PyObject *
1997select_kqueue_impl(PyTypeObject *type)
1998/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002001}
2002
2003static void
2004kqueue_queue_dealloc(kqueue_queue_Object *self)
2005{
Dino Viehlandf9190542019-09-14 15:20:27 +01002006 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002008 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2009 kqueue_free((PyObject *)self);
2010 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002011}
2012
Tal Einat6dc57e22018-06-30 23:02:48 +03002013/*[clinic input]
2014select.kqueue.close
2015
2016Close the kqueue control file descriptor.
2017
2018Further operations on the kqueue object will raise an exception.
2019[clinic start generated code]*/
2020
2021static PyObject *
2022select_kqueue_close_impl(kqueue_queue_Object *self)
2023/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 errno = kqueue_queue_internal_close(self);
2026 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002027 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 return NULL;
2029 }
2030 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002031}
2032
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002034kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 if (self->kqfd < 0)
2037 Py_RETURN_TRUE;
2038 else
2039 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040}
2041
Tal Einat6dc57e22018-06-30 23:02:48 +03002042/*[clinic input]
2043select.kqueue.fileno
2044
2045Return the kqueue control file descriptor.
2046[clinic start generated code]*/
2047
2048static PyObject *
2049select_kqueue_fileno_impl(kqueue_queue_Object *self)
2050/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 if (self->kqfd < 0)
2053 return kqueue_queue_err_closed();
2054 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002055}
2056
Tal Einat6dc57e22018-06-30 23:02:48 +03002057/*[clinic input]
2058@classmethod
2059select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002060
Tal Einat6dc57e22018-06-30 23:02:48 +03002061 fd: int
2062 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002063
Tal Einat6dc57e22018-06-30 23:02:48 +03002064Create a kqueue object from a given control fd.
2065[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002066
2067static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002068select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2069/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002070{
Tal Einat6dc57e22018-06-30 23:02:48 +03002071 SOCKET s_fd = (SOCKET)fd;
2072
2073 return newKqueue_Object(type, s_fd);
2074}
2075
2076/*[clinic input]
2077select.kqueue.control
2078
2079 changelist: object
2080 Must be an iterable of kevent objects describing the changes to be made
2081 to the kernel's watch list or None.
2082 maxevents: int
2083 The maximum number of events that the kernel will return.
2084 timeout as otimeout: object = None
2085 The maximum time to wait in seconds, or else None to wait forever.
2086 This accepts floats for smaller timeouts, too.
2087 /
2088
2089Calls the kernel kevent function.
2090[clinic start generated code]*/
2091
2092static PyObject *
2093select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2094 int maxevents, PyObject *otimeout)
2095/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 int gotevents = 0;
2098 int nchanges = 0;
2099 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002100 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 PyObject *result = NULL;
2102 struct kevent *evl = NULL;
2103 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002104 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002106 _PyTime_t timeout, deadline = 0;
Christian Heimesea97eba2020-11-21 20:29:26 +01002107 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 if (self->kqfd < 0)
2110 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002111
Tal Einat6dc57e22018-06-30 23:02:48 +03002112 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 PyErr_Format(PyExc_ValueError,
2114 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002115 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 return NULL;
2117 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002118
Tal Einat6dc57e22018-06-30 23:02:48 +03002119 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 ptimeoutspec = NULL;
2121 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002122 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002123 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002124 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002125 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002126 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002127 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002128 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002129 return NULL;
2130 }
2131
Victor Stinner4448c082015-03-31 11:48:34 +02002132 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002133 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002134
Victor Stinner4448c082015-03-31 11:48:34 +02002135 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 PyErr_SetString(PyExc_ValueError,
2137 "timeout must be positive or None");
2138 return NULL;
2139 }
Victor Stinner4448c082015-03-31 11:48:34 +02002140 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002142
Tal Einat6dc57e22018-06-30 23:02:48 +03002143 if (changelist != Py_None) {
2144 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002145 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 return NULL;
2147 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002148 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2149 PyErr_SetString(PyExc_OverflowError,
2150 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 goto error;
2152 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002153 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 chl = PyMem_New(struct kevent, nchanges);
2156 if (chl == NULL) {
2157 PyErr_NoMemory();
2158 goto error;
2159 }
Christian Heimesea97eba2020-11-21 20:29:26 +01002160 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Serhiy Storchakade072102017-10-12 22:17:46 +03002161 for (i = 0; i < nchanges; ++i) {
2162 ei = PySequence_Fast_GET_ITEM(seq, i);
Christian Heimesea97eba2020-11-21 20:29:26 +01002163 if (!kqueue_event_Check(ei, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 PyErr_SetString(PyExc_TypeError,
2165 "changelist must be an iterable of "
2166 "select.kevent objects");
2167 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002169 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002171 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002175 if (maxevents) {
2176 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 if (evl == NULL) {
2178 PyErr_NoMemory();
2179 goto error;
2180 }
2181 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002182
Victor Stinner4448c082015-03-31 11:48:34 +02002183 if (ptimeoutspec)
2184 deadline = _PyTime_GetMonotonicClock() + timeout;
2185
2186 do {
2187 Py_BEGIN_ALLOW_THREADS
2188 errno = 0;
2189 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002190 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002191 Py_END_ALLOW_THREADS
2192
2193 if (errno != EINTR)
2194 break;
2195
2196 /* kevent() was interrupted by a signal */
2197 if (PyErr_CheckSignals())
2198 goto error;
2199
2200 if (ptimeoutspec) {
2201 timeout = deadline - _PyTime_GetMonotonicClock();
2202 if (timeout < 0) {
2203 gotevents = 0;
2204 break;
2205 }
2206 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2207 goto error;
2208 /* retry kevent() with the recomputed timeout */
2209 }
2210 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002212 if (gotevents == -1) {
2213 PyErr_SetFromErrno(PyExc_OSError);
2214 goto error;
2215 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 result = PyList_New(gotevents);
2218 if (result == NULL) {
2219 goto error;
2220 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 for (i = 0; i < gotevents; i++) {
2223 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002224
Christian Heimesea97eba2020-11-21 20:29:26 +01002225 ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 if (ch == NULL) {
2227 goto error;
2228 }
2229 ch->e = evl[i];
2230 PyList_SET_ITEM(result, i, (PyObject *)ch);
2231 }
2232 PyMem_Free(chl);
2233 PyMem_Free(evl);
2234 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002235
2236 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 PyMem_Free(chl);
2238 PyMem_Free(evl);
2239 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002240 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242}
2243
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 {"closed", (getter)kqueue_queue_get_closed, NULL,
2246 "True if the kqueue handler is closed"},
2247 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002248};
2249
Tal Einat6dc57e22018-06-30 23:02:48 +03002250#endif /* HAVE_KQUEUE */
2251
2252
2253/* ************************************************************************ */
2254
2255#include "clinic/selectmodule.c.h"
2256
2257#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2258
2259static PyMethodDef poll_methods[] = {
2260 SELECT_POLL_REGISTER_METHODDEF
2261 SELECT_POLL_MODIFY_METHODDEF
2262 SELECT_POLL_UNREGISTER_METHODDEF
2263 SELECT_POLL_POLL_METHODDEF
2264 {NULL, NULL} /* sentinel */
2265};
2266
Dino Viehlandf9190542019-09-14 15:20:27 +01002267
2268static PyType_Slot poll_Type_slots[] = {
2269 {Py_tp_dealloc, poll_dealloc},
2270 {Py_tp_methods, poll_methods},
Dino Viehlandf9190542019-09-14 15:20:27 +01002271 {0, 0},
2272};
2273
2274static PyType_Spec poll_Type_spec = {
Erlend Egeberg Aasland387397f2021-04-30 15:49:17 +02002275 .name = "select.poll",
2276 .basicsize = sizeof(pollObject),
2277 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
2278 .slots = poll_Type_slots,
Tal Einat6dc57e22018-06-30 23:02:48 +03002279};
2280
2281#ifdef HAVE_SYS_DEVPOLL_H
2282
2283static PyMethodDef devpoll_methods[] = {
2284 SELECT_DEVPOLL_REGISTER_METHODDEF
2285 SELECT_DEVPOLL_MODIFY_METHODDEF
2286 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2287 SELECT_DEVPOLL_POLL_METHODDEF
2288 SELECT_DEVPOLL_CLOSE_METHODDEF
2289 SELECT_DEVPOLL_FILENO_METHODDEF
2290 {NULL, NULL} /* sentinel */
2291};
2292
Tal Einat6dc57e22018-06-30 23:02:48 +03002293#endif /* HAVE_SYS_DEVPOLL_H */
2294
2295#endif /* HAVE_POLL */
2296
2297#ifdef HAVE_EPOLL
2298
2299static PyMethodDef pyepoll_methods[] = {
2300 SELECT_EPOLL_FROMFD_METHODDEF
2301 SELECT_EPOLL_CLOSE_METHODDEF
2302 SELECT_EPOLL_FILENO_METHODDEF
2303 SELECT_EPOLL_MODIFY_METHODDEF
2304 SELECT_EPOLL_REGISTER_METHODDEF
2305 SELECT_EPOLL_UNREGISTER_METHODDEF
2306 SELECT_EPOLL_POLL_METHODDEF
2307 SELECT_EPOLL___ENTER___METHODDEF
2308 SELECT_EPOLL___EXIT___METHODDEF
2309 {NULL, NULL},
2310};
2311
Dino Viehlandf9190542019-09-14 15:20:27 +01002312static PyType_Slot pyEpoll_Type_slots[] = {
2313 {Py_tp_dealloc, pyepoll_dealloc},
2314 {Py_tp_doc, (void*)pyepoll_doc},
2315 {Py_tp_getattro, PyObject_GenericGetAttr},
2316 {Py_tp_getset, pyepoll_getsetlist},
2317 {Py_tp_methods, pyepoll_methods},
2318 {Py_tp_new, select_epoll},
2319 {0, 0},
2320};
2321
2322static PyType_Spec pyEpoll_Type_spec = {
2323 "select.epoll",
2324 sizeof(pyEpoll_Object),
2325 0,
2326 Py_TPFLAGS_DEFAULT,
2327 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002328};
2329
2330#endif /* HAVE_EPOLL */
2331
2332#ifdef HAVE_KQUEUE
2333
Tal Einat6dc57e22018-06-30 23:02:48 +03002334static PyMethodDef kqueue_queue_methods[] = {
2335 SELECT_KQUEUE_FROMFD_METHODDEF
2336 SELECT_KQUEUE_CLOSE_METHODDEF
2337 SELECT_KQUEUE_FILENO_METHODDEF
2338 SELECT_KQUEUE_CONTROL_METHODDEF
2339 {NULL, NULL},
2340};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002341
Dino Viehlandf9190542019-09-14 15:20:27 +01002342static PyType_Slot kqueue_queue_Type_slots[] = {
2343 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002344 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002345 {Py_tp_getset, kqueue_queue_getsetlist},
2346 {Py_tp_methods, kqueue_queue_methods},
2347 {Py_tp_new, select_kqueue},
2348 {0, 0},
2349};
2350
2351static PyType_Spec kqueue_queue_Type_spec = {
2352 "select.kqueue",
2353 sizeof(kqueue_queue_Object),
2354 0,
2355 Py_TPFLAGS_DEFAULT,
2356 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002357};
2358
2359#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002360
2361
2362
2363
2364
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002365/* ************************************************************************ */
2366
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002367
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002368static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002369 SELECT_SELECT_METHODDEF
2370 SELECT_POLL_METHODDEF
2371 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002373};
2374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002375PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002376"This module supports asynchronous I/O on multiple file descriptors.\n\
2377\n\
2378*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002379On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002380
Martin v. Löwis1a214512008-06-11 05:26:20 +00002381
Dino Viehlandf9190542019-09-14 15:20:27 +01002382
2383static int
2384_select_traverse(PyObject *module, visitproc visit, void *arg)
2385{
Christian Heimesea97eba2020-11-21 20:29:26 +01002386 _selectstate *state = get_select_state(module);
2387
2388 Py_VISIT(state->close);
2389 Py_VISIT(state->poll_Type);
2390 Py_VISIT(state->devpoll_Type);
2391 Py_VISIT(state->pyEpoll_Type);
2392 Py_VISIT(state->kqueue_event_Type);
2393 Py_VISIT(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002394 return 0;
2395}
2396
2397static int
2398_select_clear(PyObject *module)
2399{
Christian Heimesea97eba2020-11-21 20:29:26 +01002400 _selectstate *state = get_select_state(module);
2401
2402 Py_CLEAR(state->close);
2403 Py_CLEAR(state->poll_Type);
2404 Py_CLEAR(state->devpoll_Type);
2405 Py_CLEAR(state->pyEpoll_Type);
2406 Py_CLEAR(state->kqueue_event_Type);
2407 Py_CLEAR(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002408 return 0;
2409}
2410
2411static void
2412_select_free(void *module)
2413{
2414 _select_clear((PyObject *)module);
2415}
2416
Christian Heimesea97eba2020-11-21 20:29:26 +01002417int
2418_select_exec(PyObject *m)
Guido van Rossumed233a51992-06-23 09:07:03 +00002419{
Christian Heimesea97eba2020-11-21 20:29:26 +01002420 _selectstate *state = get_select_state(m);
Fred Drake4baedc12002-04-01 14:53:37 +00002421
Christian Heimesea97eba2020-11-21 20:29:26 +01002422 state->close = PyUnicode_InternFromString("close");
2423 if (state->close == NULL) {
2424 return -1;
2425 }
2426 if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
2427 return -1;
2428 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002429
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002430#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002431#ifdef HAVE_BROKEN_PIPE_BUF
2432#undef PIPE_BUF
2433#define PIPE_BUF 512
2434#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002435 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002436#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002437
Charles-François Natali986a56c2013-01-19 12:19:10 +01002438#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002439#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 if (select_have_broken_poll()) {
2441 if (PyObject_DelAttrString(m, "poll") == -1) {
2442 PyErr_Clear();
2443 }
2444 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002445#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002447#endif
Christian Heimesea97eba2020-11-21 20:29:26 +01002448 state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2449 m, &poll_Type_spec, NULL);
2450 if (state->poll_Type == NULL) {
2451 return -1;
2452 }
Dino Viehlandf9190542019-09-14 15:20:27 +01002453
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002454 PyModule_AddIntMacro(m, POLLIN);
2455 PyModule_AddIntMacro(m, POLLPRI);
2456 PyModule_AddIntMacro(m, POLLOUT);
2457 PyModule_AddIntMacro(m, POLLERR);
2458 PyModule_AddIntMacro(m, POLLHUP);
2459 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002460
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002461#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002462 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002463#endif
2464#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002465 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002466#endif
2467#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002468 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002469#endif
2470#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002471 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002472#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002473#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002474 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002475#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002476#ifdef POLLRDHUP
2477 /* Kernel 2.6.17+ */
2478 PyModule_AddIntMacro(m, POLLRDHUP);
2479#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002481#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002482
Jesus Cead8b9ae62011-11-14 19:07:41 +01002483#ifdef HAVE_SYS_DEVPOLL_H
Christian Heimesea97eba2020-11-21 20:29:26 +01002484 state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2485 m, &devpoll_Type_spec, NULL);
2486 if (state->devpoll_Type == NULL) {
2487 return -1;
2488 }
Jesus Cead8b9ae62011-11-14 19:07:41 +01002489#endif
2490
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002491#ifdef HAVE_EPOLL
Christian Heimesea97eba2020-11-21 20:29:26 +01002492 state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2493 m, &pyEpoll_Type_spec, NULL);
2494 if (state->pyEpoll_Type == NULL) {
2495 return -1;
2496 }
2497 if (PyModule_AddType(m, state->pyEpoll_Type) < 0) {
2498 return -1;
2499 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002500
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002501 PyModule_AddIntMacro(m, EPOLLIN);
2502 PyModule_AddIntMacro(m, EPOLLOUT);
2503 PyModule_AddIntMacro(m, EPOLLPRI);
2504 PyModule_AddIntMacro(m, EPOLLERR);
2505 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002506#ifdef EPOLLRDHUP
2507 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002508 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002509#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002510 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002511#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002513 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002514#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002515#ifdef EPOLLEXCLUSIVE
2516 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2517#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002518
2519#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002520 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002521#endif
2522#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002523 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002524#endif
2525#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002526 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002527#endif
2528#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002529 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002530#endif
2531#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002532 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002533#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002534
Benjamin Peterson95c16622011-12-27 15:36:32 -06002535#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002536 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002537#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002538#endif /* HAVE_EPOLL */
2539
2540#ifdef HAVE_KQUEUE
Christian Heimesea97eba2020-11-21 20:29:26 +01002541 state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2542 m, &kqueue_event_Type_spec, NULL);
2543 if (state->kqueue_event_Type == NULL) {
2544 return -1;
2545 }
2546 if (PyModule_AddType(m, state->kqueue_event_Type) < 0) {
2547 return -1;
2548 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002549
Christian Heimesea97eba2020-11-21 20:29:26 +01002550 state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2551 m, &kqueue_queue_Type_spec, NULL);
2552 if (state->kqueue_queue_Type == NULL) {
2553 return -1;
2554 }
2555 if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) {
2556 return -1;
2557 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558
2559 /* event filters */
2560 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2561 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002562#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002564#endif
2565#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002566 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002567#endif
2568#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002570#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002571#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002573#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002574#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 /* event flags */
2580 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2581 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2582 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2583 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2584 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2585 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002586
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002589#endif
2590#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002592#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2595 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002600#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002603#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2605 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2606 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2607 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2608 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2609 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2610 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002611#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002614#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2616 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2617 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2618 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2619 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2622 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2623 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002624#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625
2626 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002627#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002628 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2629 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2630 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002631#endif
2632
2633#endif /* HAVE_KQUEUE */
Christian Heimesea97eba2020-11-21 20:29:26 +01002634 return 0;
2635}
2636
2637static PyModuleDef_Slot _select_slots[] = {
2638 {Py_mod_exec, _select_exec},
2639 {0, NULL}
2640};
2641
2642static struct PyModuleDef selectmodule = {
2643 PyModuleDef_HEAD_INIT,
2644 .m_name = "select",
2645 .m_doc = module_doc,
2646 .m_size = sizeof(_selectstate),
2647 .m_methods = select_methods,
2648 .m_slots = _select_slots,
2649 .m_traverse = _select_traverse,
2650 .m_clear = _select_clear,
2651 .m_free = _select_free,
2652};
2653
2654PyMODINIT_FUNC
2655PyInit_select(void)
2656{
2657 return PyModuleDef_Init(&selectmodule);
Guido van Rossumed233a51992-06-23 09:07:03 +00002658}