blob: 3afcb0e2a02206d4199239149ae83b9c708d8ae9 [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
Tal Einatf6e59722022-01-21 11:02:25 +0200567 The maximum time to wait in milliseconds, or else None (or a negative
568 value) to wait indefinitely.
Tal Einat6dc57e22018-06-30 23:02:48 +0300569 /
570
571Polls the set of registered file descriptors.
572
573Returns a list containing any descriptors that have events or errors to
574report, as a list of (fd, event) 2-tuples.
575[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000576
577static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300578select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
Tal Einatf6e59722022-01-21 11:02:25 +0200579/*[clinic end generated code: output=876e837d193ed7e4 input=c2f6953ec45e5622]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000580{
Tal Einat6dc57e22018-06-30 23:02:48 +0300581 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200582 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200584 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200585 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000586
Tal Einat6dc57e22018-06-30 23:02:48 +0300587 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200588 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100589 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200590 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
591 PyErr_SetString(PyExc_TypeError,
592 "timeout must be an integer or None");
593 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200595 }
596
Pablo Galindo2c15b292017-10-17 15:14:41 +0100597 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200598 if (ms < INT_MIN || ms > INT_MAX) {
599 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200601 }
602
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200603 if (timeout >= 0) {
604 deadline = _PyTime_GetMonotonicClock() + timeout;
605 }
606 }
607
608 /* On some OSes, typically BSD-based ones, the timeout parameter of the
609 poll() syscall, when negative, must be exactly INFTIM, where defined,
610 or -1. See issue 31334. */
611 if (ms < 0) {
612#ifdef INFTIM
613 ms = INFTIM;
614#else
615 ms = -1;
616#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000618
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300619 /* Avoid concurrent poll() invocation, issue 8865 */
620 if (self->poll_running) {
621 PyErr_SetString(PyExc_RuntimeError,
622 "concurrent poll() invocation");
623 return NULL;
624 }
625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 /* Ensure the ufd array is up to date */
627 if (!self->ufd_uptodate)
628 if (update_ufd_array(self) == 0)
629 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000630
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300631 self->poll_running = 1;
632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200634 async_err = 0;
635 do {
636 Py_BEGIN_ALLOW_THREADS
637 errno = 0;
638 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
639 Py_END_ALLOW_THREADS
640
641 if (errno != EINTR)
642 break;
643
644 /* poll() was interrupted by a signal */
645 if (PyErr_CheckSignals()) {
646 async_err = 1;
647 break;
648 }
649
650 if (timeout >= 0) {
651 timeout = deadline - _PyTime_GetMonotonicClock();
652 if (timeout < 0) {
653 poll_result = 0;
654 break;
655 }
656 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
657 /* retry poll() with the recomputed timeout */
658 }
659 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000660
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300661 self->poll_running = 0;
662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200664 if (!async_err)
665 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 return NULL;
667 }
668
669 /* build the result list */
670
671 result_list = PyList_New(poll_result);
672 if (!result_list)
673 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200675 for (i = 0, j = 0; j < poll_result; j++) {
676 /* skip to the next fired descriptor */
677 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 i++;
679 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200680 /* if we hit a NULL return, set value to NULL
681 and break out of loop; code at end will
682 clean up result_list */
683 value = PyTuple_New(2);
684 if (value == NULL)
685 goto error;
686 num = PyLong_FromLong(self->ufds[i].fd);
687 if (num == NULL) {
688 Py_DECREF(value);
689 goto error;
690 }
691 PyTuple_SET_ITEM(value, 0, num);
692
693 /* The &0xffff is a workaround for AIX. 'revents'
694 is a 16-bit short, and IBM assigned POLLNVAL
695 to be 0x8000, so the conversion to int results
696 in a negative number. See SF bug #923315. */
697 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
698 if (num == NULL) {
699 Py_DECREF(value);
700 goto error;
701 }
702 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700703 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200704 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 }
706 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000707
708 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 Py_DECREF(result_list);
710 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000711}
712
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000713static pollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +0100714newPollObject(PyObject *module)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 pollObject *self;
Christian Heimesea97eba2020-11-21 20:29:26 +0100717 self = PyObject_New(pollObject, get_select_state(module)->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 if (self == NULL)
719 return NULL;
720 /* ufd_uptodate is a Boolean, denoting whether the
721 array pointed to by ufds matches the contents of the dictionary. */
722 self->ufd_uptodate = 0;
723 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300724 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 self->dict = PyDict_New();
726 if (self->dict == NULL) {
727 Py_DECREF(self);
728 return NULL;
729 }
730 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000731}
732
733static void
734poll_dealloc(pollObject *self)
735{
Dino Viehlandf9190542019-09-14 15:20:27 +0100736 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 if (self->ufds != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100738 PyMem_Free(self->ufds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 Py_XDECREF(self->dict);
Victor Stinner32bd68c2020-12-01 10:37:39 +0100740 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100741 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000742}
743
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000744
Jesus Cead8b9ae62011-11-14 19:07:41 +0100745#ifdef HAVE_SYS_DEVPOLL_H
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300746static PyMethodDef devpoll_methods[];
747
Jesus Cead8b9ae62011-11-14 19:07:41 +0100748typedef struct {
749 PyObject_HEAD
750 int fd_devpoll;
751 int max_n_fds;
752 int n_fds;
753 struct pollfd *fds;
754} devpollObject;
755
Victor Stinner13423c32013-08-22 00:19:50 +0200756static PyObject *
757devpoll_err_closed(void)
758{
759 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
760 return NULL;
761}
762
Jesus Cead8b9ae62011-11-14 19:07:41 +0100763static int devpoll_flush(devpollObject *self)
764{
765 int size, n;
766
767 if (!self->n_fds) return 0;
768
769 size = sizeof(struct pollfd)*self->n_fds;
770 self->n_fds = 0;
771
Victor Stinner54799672015-03-19 23:33:09 +0100772 n = _Py_write(self->fd_devpoll, self->fds, size);
773 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100774 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100775
Jesus Cead8b9ae62011-11-14 19:07:41 +0100776 if (n < size) {
777 /*
778 ** Data writed to /dev/poll is a binary data structure. It is not
779 ** clear what to do if a partial write occurred. For now, raise
780 ** an exception and see if we actually found this problem in
781 ** the wild.
782 ** See http://bugs.python.org/issue6397.
783 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300784 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100785 "Please, report at http://bugs.python.org/. "
786 "Data to report: Size tried: %d, actual size written: %d.",
787 size, n);
788 return -1;
789 }
790 return 0;
791}
792
793static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300794internal_devpoll_register(devpollObject *self, int fd,
795 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100796{
Victor Stinner13423c32013-08-22 00:19:50 +0200797 if (self->fd_devpoll < 0)
798 return devpoll_err_closed();
799
Jesus Cead8b9ae62011-11-14 19:07:41 +0100800 if (remove) {
801 self->fds[self->n_fds].fd = fd;
802 self->fds[self->n_fds].events = POLLREMOVE;
803
804 if (++self->n_fds == self->max_n_fds) {
805 if (devpoll_flush(self))
806 return NULL;
807 }
808 }
809
810 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200811 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100812
813 if (++self->n_fds == self->max_n_fds) {
814 if (devpoll_flush(self))
815 return NULL;
816 }
817
818 Py_RETURN_NONE;
819}
820
Tal Einat6dc57e22018-06-30 23:02:48 +0300821/*[clinic input]
822select.devpoll.register
823
824 fd: fildes
825 either an integer, or an object with a fileno() method returning
826 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700827 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300828 an optional bitmask describing the type of events to check for
829 /
830
831Register a file descriptor with the polling object.
832[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100833
834static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300835select_devpoll_register_impl(devpollObject *self, int fd,
836 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700837/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100838{
Tal Einat6dc57e22018-06-30 23:02:48 +0300839 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100840}
841
Tal Einat6dc57e22018-06-30 23:02:48 +0300842/*[clinic input]
843select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100844
Tal Einat6dc57e22018-06-30 23:02:48 +0300845 fd: fildes
846 either an integer, or an object with a fileno() method returning
847 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700848 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300849 an optional bitmask describing the type of events to check for
850 /
851
852Modify a possible already registered file descriptor.
853[clinic start generated code]*/
854
855static PyObject *
856select_devpoll_modify_impl(devpollObject *self, int fd,
857 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700858/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859{
Tal Einat6dc57e22018-06-30 23:02:48 +0300860 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100861}
862
Tal Einat6dc57e22018-06-30 23:02:48 +0300863/*[clinic input]
864select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100865
Tal Einat6dc57e22018-06-30 23:02:48 +0300866 fd: fildes
867 /
868
869Remove a file descriptor being tracked by the polling object.
870[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100871
872static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300873select_devpoll_unregister_impl(devpollObject *self, int fd)
874/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100875{
Victor Stinner13423c32013-08-22 00:19:50 +0200876 if (self->fd_devpoll < 0)
877 return devpoll_err_closed();
878
Jesus Cead8b9ae62011-11-14 19:07:41 +0100879 self->fds[self->n_fds].fd = fd;
880 self->fds[self->n_fds].events = POLLREMOVE;
881
882 if (++self->n_fds == self->max_n_fds) {
883 if (devpoll_flush(self))
884 return NULL;
885 }
886
887 Py_RETURN_NONE;
888}
889
Tal Einat6dc57e22018-06-30 23:02:48 +0300890/*[clinic input]
891select.devpoll.poll
892 timeout as timeout_obj: object = None
Tal Einatf6e59722022-01-21 11:02:25 +0200893 The maximum time to wait in milliseconds, or else None (or a negative
894 value) to wait indefinitely.
Tal Einat6dc57e22018-06-30 23:02:48 +0300895 /
896
897Polls the set of registered file descriptors.
898
899Returns a list containing any descriptors that have events or errors to
900report, as a list of (fd, event) 2-tuples.
901[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902
903static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300904select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
Tal Einatf6e59722022-01-21 11:02:25 +0200905/*[clinic end generated code: output=2654e5457cca0b3c input=3c3f0a355ec2bedb]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100906{
907 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200908 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100910 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200911 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912
Victor Stinner13423c32013-08-22 00:19:50 +0200913 if (self->fd_devpoll < 0)
914 return devpoll_err_closed();
915
Jesus Cead8b9ae62011-11-14 19:07:41 +0100916 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300917 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100918 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200919 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920 }
921 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200922 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100923 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200924 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
925 PyErr_SetString(PyExc_TypeError,
926 "timeout must be an integer or None");
927 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200929 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100930
Pablo Galindo2c15b292017-10-17 15:14:41 +0100931 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 if (ms < -1 || ms > INT_MAX) {
933 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
934 return NULL;
935 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100936 }
937
938 if (devpoll_flush(self))
939 return NULL;
940
941 dvp.dp_fds = self->fds;
942 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200943 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100944
Victor Stinner45ca48b2015-03-31 12:10:33 +0200945 if (timeout >= 0)
946 deadline = _PyTime_GetMonotonicClock() + timeout;
947
948 do {
949 /* call devpoll() */
950 Py_BEGIN_ALLOW_THREADS
951 errno = 0;
952 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
953 Py_END_ALLOW_THREADS
954
955 if (errno != EINTR)
956 break;
957
958 /* devpoll() was interrupted by a signal */
959 if (PyErr_CheckSignals())
960 return NULL;
961
962 if (timeout >= 0) {
963 timeout = deadline - _PyTime_GetMonotonicClock();
964 if (timeout < 0) {
965 poll_result = 0;
966 break;
967 }
968 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
969 dvp.dp_timeout = (int)ms;
970 /* retry devpoll() with the recomputed timeout */
971 }
972 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100973
974 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300975 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976 return NULL;
977 }
978
979 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100980 result_list = PyList_New(poll_result);
981 if (!result_list)
982 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200983
984 for (i = 0; i < poll_result; i++) {
985 num1 = PyLong_FromLong(self->fds[i].fd);
986 num2 = PyLong_FromLong(self->fds[i].revents);
987 if ((num1 == NULL) || (num2 == NULL)) {
988 Py_XDECREF(num1);
989 Py_XDECREF(num2);
990 goto error;
991 }
992 value = PyTuple_Pack(2, num1, num2);
993 Py_DECREF(num1);
994 Py_DECREF(num2);
995 if (value == NULL)
996 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -0700997 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100998 }
999
1000 return result_list;
1001
1002 error:
1003 Py_DECREF(result_list);
1004 return NULL;
1005}
1006
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001007static int
1008devpoll_internal_close(devpollObject *self)
1009{
1010 int save_errno = 0;
1011 if (self->fd_devpoll >= 0) {
1012 int fd = self->fd_devpoll;
1013 self->fd_devpoll = -1;
1014 Py_BEGIN_ALLOW_THREADS
1015 if (close(fd) < 0)
1016 save_errno = errno;
1017 Py_END_ALLOW_THREADS
1018 }
1019 return save_errno;
1020}
1021
Tal Einat6dc57e22018-06-30 23:02:48 +03001022/*[clinic input]
1023select.devpoll.close
1024
1025Close the devpoll file descriptor.
1026
1027Further operations on the devpoll object will raise an exception.
1028[clinic start generated code]*/
1029
1030static PyObject *
1031select_devpoll_close_impl(devpollObject *self)
1032/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001033{
1034 errno = devpoll_internal_close(self);
1035 if (errno < 0) {
1036 PyErr_SetFromErrno(PyExc_OSError);
1037 return NULL;
1038 }
1039 Py_RETURN_NONE;
1040}
1041
Victor Stinner13423c32013-08-22 00:19:50 +02001042static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001043devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001044{
1045 if (self->fd_devpoll < 0)
1046 Py_RETURN_TRUE;
1047 else
1048 Py_RETURN_FALSE;
1049}
1050
Tal Einat6dc57e22018-06-30 23:02:48 +03001051/*[clinic input]
1052select.devpoll.fileno
1053
1054Return the file descriptor.
1055[clinic start generated code]*/
1056
1057static PyObject *
1058select_devpoll_fileno_impl(devpollObject *self)
1059/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001060{
1061 if (self->fd_devpoll < 0)
1062 return devpoll_err_closed();
1063 return PyLong_FromLong(self->fd_devpoll);
1064}
1065
Victor Stinner13423c32013-08-22 00:19:50 +02001066static PyGetSetDef devpoll_getsetlist[] = {
1067 {"closed", (getter)devpoll_get_closed, NULL,
1068 "True if the devpoll object is closed"},
1069 {0},
1070};
1071
Jesus Cead8b9ae62011-11-14 19:07:41 +01001072static devpollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +01001073newDevPollObject(PyObject *module)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001074{
1075 devpollObject *self;
1076 int fd_devpoll, limit_result;
1077 struct pollfd *fds;
1078 struct rlimit limit;
1079
Jesus Cead8b9ae62011-11-14 19:07:41 +01001080 /*
1081 ** If we try to process more that getrlimit()
1082 ** fds, the kernel will give an error, so
1083 ** we set the limit here. It is a dynamic
1084 ** value, because we can change rlimit() anytime.
1085 */
1086 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001087 if (limit_result == -1) {
1088 PyErr_SetFromErrno(PyExc_OSError);
1089 return NULL;
1090 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001091
1092 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1093 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001094 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001095
1096 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1097 if (fds == NULL) {
1098 close(fd_devpoll);
1099 PyErr_NoMemory();
1100 return NULL;
1101 }
1102
Christian Heimesea97eba2020-11-21 20:29:26 +01001103 self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001104 if (self == NULL) {
1105 close(fd_devpoll);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001106 PyMem_Free(fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001107 return NULL;
1108 }
1109 self->fd_devpoll = fd_devpoll;
1110 self->max_n_fds = limit.rlim_cur;
1111 self->n_fds = 0;
1112 self->fds = fds;
1113
1114 return self;
1115}
1116
1117static void
1118devpoll_dealloc(devpollObject *self)
1119{
Dino Viehlandf9190542019-09-14 15:20:27 +01001120 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001121 (void)devpoll_internal_close(self);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001122 PyMem_Free(self->fds);
Victor Stinner32bd68c2020-12-01 10:37:39 +01001123 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001124 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001125}
1126
Dino Viehlandf9190542019-09-14 15:20:27 +01001127static PyType_Slot devpoll_Type_slots[] = {
1128 {Py_tp_dealloc, devpoll_dealloc},
1129 {Py_tp_getset, devpoll_getsetlist},
1130 {Py_tp_methods, devpoll_methods},
Dino Viehlandf9190542019-09-14 15:20:27 +01001131 {0, 0},
1132};
1133
1134static PyType_Spec devpoll_Type_spec = {
1135 "select.devpoll",
1136 sizeof(devpollObject),
1137 0,
Victor Stinner7dcf0f62021-04-30 18:19:57 +02001138 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
Dino Viehlandf9190542019-09-14 15:20:27 +01001139 devpoll_Type_slots
1140};
1141
Jesus Cead8b9ae62011-11-14 19:07:41 +01001142#endif /* HAVE_SYS_DEVPOLL_H */
1143
1144
Tal Einat6dc57e22018-06-30 23:02:48 +03001145/*[clinic input]
1146select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001147
Tal Einat6dc57e22018-06-30 23:02:48 +03001148Returns a polling object.
1149
1150This object supports registering and unregistering file descriptors, and then
1151polling them for I/O events.
1152[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001153
1154static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001155select_poll_impl(PyObject *module)
1156/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001157{
Christian Heimesea97eba2020-11-21 20:29:26 +01001158 return (PyObject *)newPollObject(module);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001159}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001160
Jesus Cead8b9ae62011-11-14 19:07:41 +01001161#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001162
1163/*[clinic input]
1164select.devpoll
1165
1166Returns a polling object.
1167
1168This object supports registering and unregistering file descriptors, and then
1169polling them for I/O events.
1170[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001171
1172static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001173select_devpoll_impl(PyObject *module)
1174/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001175{
Christian Heimesea97eba2020-11-21 20:29:26 +01001176 return (PyObject *)newDevPollObject(module);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001177}
1178#endif
1179
1180
Thomas Wouters477c8d52006-05-27 19:21:47 +00001181#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001183 * On some systems poll() sets errno on invalid file descriptors. We test
1184 * for this at runtime because this bug may be fixed or introduced between
1185 * OS releases.
1186 */
1187static int select_have_broken_poll(void)
1188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 int poll_test;
1190 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 /* Create a file descriptor to make invalid */
1195 if (pipe(filedes) < 0) {
1196 return 1;
1197 }
1198 poll_struct.fd = filedes[0];
1199 close(filedes[0]);
1200 close(filedes[1]);
1201 poll_test = poll(&poll_struct, 1, 0);
1202 if (poll_test < 0) {
1203 return 1;
1204 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1205 return 1;
1206 }
1207 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208}
1209#endif /* __APPLE__ */
1210
1211#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001212
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001213#ifdef HAVE_EPOLL
1214/* **************************************************************************
1215 * epoll interface for Linux 2.6
1216 *
1217 * Written by Christian Heimes
1218 * Inspired by Twisted's _epoll.pyx and select.poll()
1219 */
1220
1221#ifdef HAVE_SYS_EPOLL_H
1222#include <sys/epoll.h>
1223#endif
1224
1225typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001227 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001228} pyEpoll_Object;
1229
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001230static PyObject *
1231pyepoll_err_closed(void)
1232{
Victor Stinner13423c32013-08-22 00:19:50 +02001233 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001235}
1236
1237static int
1238pyepoll_internal_close(pyEpoll_Object *self)
1239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 int save_errno = 0;
1241 if (self->epfd >= 0) {
1242 int epfd = self->epfd;
1243 self->epfd = -1;
1244 Py_BEGIN_ALLOW_THREADS
1245 if (close(epfd) < 0)
1246 save_errno = errno;
1247 Py_END_ALLOW_THREADS
1248 }
1249 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250}
1251
1252static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001253newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001256 assert(type != NULL);
1257 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1258 assert(epoll_alloc != NULL);
1259 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (self == NULL)
1261 return NULL;
1262
1263 if (fd == -1) {
1264 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001265#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001266 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1267#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001268 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001269#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 Py_END_ALLOW_THREADS
1271 }
1272 else {
1273 self->epfd = fd;
1274 }
1275 if (self->epfd < 0) {
1276 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001277 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 return NULL;
1279 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001280
1281#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001282 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001283 Py_DECREF(self);
1284 return NULL;
1285 }
1286#endif
1287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001289}
1290
1291
Tal Einat6dc57e22018-06-30 23:02:48 +03001292/*[clinic input]
1293@classmethod
1294select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001295
Tal Einat6dc57e22018-06-30 23:02:48 +03001296 sizehint: int = -1
1297 The expected number of events to be registered. It must be positive,
1298 or -1 to use the default. It is only used on older systems where
1299 epoll_create1() is not available; otherwise it has no effect (though its
1300 value is still checked).
1301 flags: int = 0
1302 Deprecated and completely ignored. However, when supplied, its value
1303 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1304
1305Returns an epolling object.
1306[clinic start generated code]*/
1307
1308static PyObject *
1309select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1310/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1311{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001312 if (sizehint == -1) {
1313 sizehint = FD_SETSIZE - 1;
1314 }
1315 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001316 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001317 return NULL;
1318 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001319
1320#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001321 if (flags && flags != EPOLL_CLOEXEC) {
1322 PyErr_SetString(PyExc_OSError, "invalid flags");
1323 return NULL;
1324 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001325#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001326
Berker Peksage2197d12016-09-26 23:30:41 +03001327 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001328}
1329
1330
1331static void
1332pyepoll_dealloc(pyEpoll_Object *self)
1333{
Dino Viehlandf9190542019-09-14 15:20:27 +01001334 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001336 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1337 epoll_free((PyObject *)self);
1338 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001339}
1340
Tal Einat6dc57e22018-06-30 23:02:48 +03001341/*[clinic input]
1342select.epoll.close
1343
1344Close the epoll control file descriptor.
1345
1346Further operations on the epoll object will raise an exception.
1347[clinic start generated code]*/
1348
1349static PyObject *
1350select_epoll_close_impl(pyEpoll_Object *self)
1351/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 errno = pyepoll_internal_close(self);
1354 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001355 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 return NULL;
1357 }
1358 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359}
1360
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361
1362static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001363pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 if (self->epfd < 0)
1366 Py_RETURN_TRUE;
1367 else
1368 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001369}
1370
Tal Einat6dc57e22018-06-30 23:02:48 +03001371/*[clinic input]
1372select.epoll.fileno
1373
1374Return the epoll control file descriptor.
1375[clinic start generated code]*/
1376
1377static PyObject *
1378select_epoll_fileno_impl(pyEpoll_Object *self)
1379/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 if (self->epfd < 0)
1382 return pyepoll_err_closed();
1383 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384}
1385
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386
Tal Einat6dc57e22018-06-30 23:02:48 +03001387/*[clinic input]
1388@classmethod
1389select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
Tal Einat6dc57e22018-06-30 23:02:48 +03001391 fd: int
1392 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393
Tal Einat6dc57e22018-06-30 23:02:48 +03001394Create an epoll object from a given control fd.
1395[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001396
1397static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001398select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1399/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1400{
1401 SOCKET s_fd = (SOCKET)fd;
1402 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1403}
1404
1405
1406static PyObject *
1407pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 struct epoll_event ev;
1410 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 if (epfd < 0)
1413 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001414
Guido van Rossumee07b942013-12-06 17:46:22 -08001415 switch (op) {
1416 case EPOLL_CTL_ADD:
1417 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 ev.events = events;
1419 ev.data.fd = fd;
1420 Py_BEGIN_ALLOW_THREADS
1421 result = epoll_ctl(epfd, op, fd, &ev);
1422 Py_END_ALLOW_THREADS
1423 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001424 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1426 * operation required a non-NULL pointer in event, even
1427 * though this argument is ignored. */
1428 Py_BEGIN_ALLOW_THREADS
1429 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 Py_END_ALLOW_THREADS
1431 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001432 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 result = -1;
1434 errno = EINVAL;
1435 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001438 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 return NULL;
1440 }
1441 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001442}
1443
Tal Einat6dc57e22018-06-30 23:02:48 +03001444/*[clinic input]
1445select.epoll.register
1446
1447 fd: fildes
1448 the target file descriptor of the operation
Anthony Sottiled0518012020-06-23 14:49:56 -07001449 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001450 a bit set composed of the various EPOLL constants
1451
1452Registers a new fd or raises an OSError if the fd is already registered.
1453
1454The epoll interface supports all file descriptors that support poll.
1455[clinic start generated code]*/
1456
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001457static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001458select_epoll_register_impl(pyEpoll_Object *self, int fd,
1459 unsigned int eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -07001460/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461{
Tal Einat6dc57e22018-06-30 23:02:48 +03001462 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001463}
1464
Tal Einat6dc57e22018-06-30 23:02:48 +03001465/*[clinic input]
1466select.epoll.modify
1467
1468 fd: fildes
1469 the target file descriptor of the operation
1470 eventmask: unsigned_int(bitwise=True)
1471 a bit set composed of the various EPOLL constants
1472
1473Modify event mask for a registered file descriptor.
1474[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001475
1476static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001477select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1478 unsigned int eventmask)
1479/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480{
Tal Einat6dc57e22018-06-30 23:02:48 +03001481 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001482}
1483
Tal Einat6dc57e22018-06-30 23:02:48 +03001484/*[clinic input]
1485select.epoll.unregister
1486
1487 fd: fildes
1488 the target file descriptor of the operation
1489
1490Remove a registered file descriptor from the epoll object.
1491[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001492
1493static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001494select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1495/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001496{
Tal Einat6dc57e22018-06-30 23:02:48 +03001497 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001498}
1499
Tal Einat6dc57e22018-06-30 23:02:48 +03001500/*[clinic input]
1501select.epoll.poll
1502
1503 timeout as timeout_obj: object = None
1504 the maximum time to wait in seconds (as float);
1505 a timeout of None or -1 makes poll wait indefinitely
1506 maxevents: int = -1
1507 the maximum number of events returned; -1 means no limit
1508
1509Wait for events on the epoll file descriptor.
1510
1511Returns a list containing any descriptors that have events to report,
1512as a list of (fd, events) 2-tuples.
1513[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001514
1515static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001516select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1517 int maxevents)
1518/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 int nfds, i;
1521 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001522 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001523 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 if (self->epfd < 0)
1526 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001527
Berker Peksagb690b9b2018-09-11 20:29:48 +03001528 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001529 /* epoll_wait() has a resolution of 1 millisecond, round towards
1530 infinity to wait at least timeout seconds. */
1531 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001532 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001533 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1534 PyErr_SetString(PyExc_TypeError,
1535 "timeout must be an integer or None");
1536 }
1537 return NULL;
1538 }
1539
1540 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1541 if (ms < INT_MIN || ms > INT_MAX) {
1542 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1543 return NULL;
1544 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001545 /* epoll_wait(2) treats all arbitrary negative numbers the same
1546 for the timeout argument, but -1 is the documented way to block
1547 indefinitely in the epoll_wait(2) documentation, so we set ms
1548 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001549
Berker Peksagb690b9b2018-09-11 20:29:48 +03001550 Note that we didn't use INFTIM here since it's non-standard and
1551 isn't available under Linux. */
1552 if (ms < 0) {
1553 ms = -1;
1554 }
1555
1556 if (timeout >= 0) {
1557 deadline = _PyTime_GetMonotonicClock() + timeout;
1558 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001562 maxevents = FD_SETSIZE-1;
1563 }
1564 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 PyErr_Format(PyExc_ValueError,
1566 "maxevents must be greater than 0, got %d",
1567 maxevents);
1568 return NULL;
1569 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001570
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001571 evs = PyMem_New(struct epoll_event, maxevents);
1572 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001573 PyErr_NoMemory();
1574 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001576
Victor Stinner41eba222015-03-30 21:59:21 +02001577 do {
1578 Py_BEGIN_ALLOW_THREADS
1579 errno = 0;
1580 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1581 Py_END_ALLOW_THREADS
1582
1583 if (errno != EINTR)
1584 break;
1585
1586 /* poll() was interrupted by a signal */
1587 if (PyErr_CheckSignals())
1588 goto error;
1589
1590 if (timeout >= 0) {
1591 timeout = deadline - _PyTime_GetMonotonicClock();
1592 if (timeout < 0) {
1593 nfds = 0;
1594 break;
1595 }
1596 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1597 /* retry epoll_wait() with the recomputed timeout */
1598 }
1599 } while(1);
1600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001602 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 goto error;
1604 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 elist = PyList_New(nfds);
1607 if (elist == NULL) {
1608 goto error;
1609 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001612 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 if (etuple == NULL) {
1614 Py_CLEAR(elist);
1615 goto error;
1616 }
1617 PyList_SET_ITEM(elist, i, etuple);
1618 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001619
Christian Heimesf6cd9672008-03-26 13:45:42 +00001620 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001621 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001623}
1624
Tal Einat6dc57e22018-06-30 23:02:48 +03001625
1626/*[clinic input]
1627select.epoll.__enter__
1628
1629[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001631static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001632select_epoll___enter___impl(pyEpoll_Object *self)
1633/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001634{
1635 if (self->epfd < 0)
1636 return pyepoll_err_closed();
1637
1638 Py_INCREF(self);
1639 return (PyObject *)self;
1640}
1641
Tal Einat6dc57e22018-06-30 23:02:48 +03001642/*[clinic input]
1643select.epoll.__exit__
1644
1645 exc_type: object = None
1646 exc_value: object = None
1647 exc_tb: object = None
1648 /
1649
1650[clinic start generated code]*/
1651
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001652static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001653select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1654 PyObject *exc_value, PyObject *exc_tb)
1655/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001656{
Christian Heimesea97eba2020-11-21 20:29:26 +01001657 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
1658 return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001659}
1660
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001661static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 {"closed", (getter)pyepoll_get_closed, NULL,
1663 "True if the epoll handler is closed"},
1664 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001665};
1666
Dino Viehlandf9190542019-09-14 15:20:27 +01001667PyDoc_STRVAR(pyepoll_doc,
1668"select.epoll(sizehint=-1, flags=0)\n\
1669\n\
1670Returns an epolling object\n\
1671\n\
1672sizehint must be a positive integer or -1 for the default size. The\n\
1673sizehint is used to optimize internal data structures. It doesn't limit\n\
1674the maximum number of monitored events.");
1675
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001676#endif /* HAVE_EPOLL */
1677
1678#ifdef HAVE_KQUEUE
1679/* **************************************************************************
1680 * kqueue interface for BSD
1681 *
1682 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1683 * All rights reserved.
1684 *
1685 * Redistribution and use in source and binary forms, with or without
1686 * modification, are permitted provided that the following conditions
1687 * are met:
1688 * 1. Redistributions of source code must retain the above copyright
1689 * notice, this list of conditions and the following disclaimer.
1690 * 2. Redistributions in binary form must reproduce the above copyright
1691 * notice, this list of conditions and the following disclaimer in the
1692 * documentation and/or other materials provided with the distribution.
1693 *
1694 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1695 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1696 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1697 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1698 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1699 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1700 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1701 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1702 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1703 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1704 * SUCH DAMAGE.
1705 */
1706
1707#ifdef HAVE_SYS_EVENT_H
1708#include <sys/event.h>
1709#endif
1710
1711PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001712"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001713\n\
1714This object is the equivalent of the struct kevent for the C API.\n\
1715\n\
1716See the kqueue manpage for more detailed information about the meaning\n\
1717of the arguments.\n\
1718\n\
1719One minor note: while you might hope that udata could store a\n\
1720reference to a python object, it cannot, because it is impossible to\n\
1721keep a proper reference count of the object once it's passed into the\n\
1722kernel. Therefore, I have restricted it to only storing an integer. I\n\
1723recommend ignoring it and simply using the 'ident' field to key off\n\
1724of. You could also set up a dictionary on the python side to store a\n\
1725udata->object mapping.");
1726
1727typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 PyObject_HEAD
1729 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001730} kqueue_event_Object;
1731
Christian Heimesea97eba2020-11-21 20:29:26 +01001732#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001733
1734typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 PyObject_HEAD
1736 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001737} kqueue_queue_Object;
1738
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001739#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1740# error uintptr_t does not match void *!
1741#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1742# define T_UINTPTRT T_ULONGLONG
1743# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001744# define UINTPTRT_FMT_UNIT "K"
1745# define INTPTRT_FMT_UNIT "L"
1746#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1747# define T_UINTPTRT T_ULONG
1748# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001749# define UINTPTRT_FMT_UNIT "k"
1750# define INTPTRT_FMT_UNIT "l"
1751#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1752# define T_UINTPTRT T_UINT
1753# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001754# define UINTPTRT_FMT_UNIT "I"
1755# define INTPTRT_FMT_UNIT "i"
1756#else
1757# error uintptr_t does not match int, long, or long long!
1758#endif
1759
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001760#if SIZEOF_LONG_LONG == 8
1761# define T_INT64 T_LONGLONG
1762# define INT64_FMT_UNIT "L"
1763#elif SIZEOF_LONG == 8
1764# define T_INT64 T_LONG
1765# define INT64_FMT_UNIT "l"
1766#elif SIZEOF_INT == 8
1767# define T_INT64 T_INT
1768# define INT64_FMT_UNIT "i"
1769#else
1770# define INT64_FMT_UNIT "_"
1771#endif
1772
1773#if SIZEOF_LONG_LONG == 4
1774# define T_UINT32 T_ULONGLONG
1775# define UINT32_FMT_UNIT "K"
1776#elif SIZEOF_LONG == 4
1777# define T_UINT32 T_ULONG
1778# define UINT32_FMT_UNIT "k"
1779#elif SIZEOF_INT == 4
1780# define T_UINT32 T_UINT
1781# define UINT32_FMT_UNIT "I"
1782#else
1783# define UINT32_FMT_UNIT "_"
1784#endif
1785
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001786/*
1787 * kevent is not standard and its members vary across BSDs.
1788 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001789#ifdef __NetBSD__
1790# define FILTER_TYPE T_UINT32
1791# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1792# define FLAGS_TYPE T_UINT32
1793# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1794# define FFLAGS_TYPE T_UINT32
1795# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001796#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001797# define FILTER_TYPE T_SHORT
1798# define FILTER_FMT_UNIT "h"
1799# define FLAGS_TYPE T_USHORT
1800# define FLAGS_FMT_UNIT "H"
1801# define FFLAGS_TYPE T_UINT
1802# define FFLAGS_FMT_UNIT "I"
1803#endif
1804
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001805#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001806# define DATA_TYPE T_INT64
1807# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001808#else
1809# define DATA_TYPE T_INTPTRT
1810# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001811#endif
1812
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001813/* Unfortunately, we can't store python objects in udata, because
1814 * kevents in the kernel can be removed without warning, which would
1815 * forever lose the refcount on the object stored with it.
1816 */
1817
1818#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1819static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001820 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1821 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1822 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001824 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1826 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001827};
1828#undef KQ_OFF
1829
1830static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001831
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001832kqueue_event_repr(kqueue_event_Object *s)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 char buf[1024];
1835 PyOS_snprintf(
1836 buf, sizeof(buf),
1837 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001838 "data=0x%llx udata=%p>",
1839 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1840 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001842}
1843
1844static int
1845kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 PyObject *pfd;
1848 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1849 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001850 static const char fmt[] = "O|"
1851 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1852 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1857 &pfd, &(self->e.filter), &(self->e.flags),
1858 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1859 return -1;
1860 }
1861
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001862 if (PyLong_Check(pfd)) {
1863 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 }
1865 else {
1866 self->e.ident = PyObject_AsFileDescriptor(pfd);
1867 }
1868 if (PyErr_Occurred()) {
1869 return -1;
1870 }
1871 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001872}
1873
1874static PyObject *
1875kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001878 int result;
Christian Heimesea97eba2020-11-21 20:29:26 +01001879 _selectstate *state = _selectstate_by_type(Py_TYPE(s));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880
Christian Heimesea97eba2020-11-21 20:29:26 +01001881 if (!kqueue_event_Check(o, state)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001882 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001884
1885#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1886 result = CMP(s->e.ident, o->e.ident)
1887 : CMP(s->e.filter, o->e.filter)
1888 : CMP(s->e.flags, o->e.flags)
1889 : CMP(s->e.fflags, o->e.fflags)
1890 : CMP(s->e.data, o->e.data)
1891 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1892 : 0;
1893#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001894
stratakise8b19652017-11-02 11:32:54 +01001895 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896}
1897
Dino Viehlandf9190542019-09-14 15:20:27 +01001898static PyType_Slot kqueue_event_Type_slots[] = {
1899 {Py_tp_doc, (void*)kqueue_event_doc},
1900 {Py_tp_init, kqueue_event_init},
1901 {Py_tp_members, kqueue_event_members},
1902 {Py_tp_new, PyType_GenericNew},
1903 {Py_tp_repr, kqueue_event_repr},
1904 {Py_tp_richcompare, kqueue_event_richcompare},
1905 {0, 0},
1906};
1907
1908static PyType_Spec kqueue_event_Type_spec = {
1909 "select.kevent",
1910 sizeof(kqueue_event_Object),
1911 0,
1912 Py_TPFLAGS_DEFAULT,
1913 kqueue_event_Type_slots
1914};
1915
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001916static PyObject *
1917kqueue_queue_err_closed(void)
1918{
Victor Stinner13423c32013-08-22 00:19:50 +02001919 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921}
1922
1923static int
1924kqueue_queue_internal_close(kqueue_queue_Object *self)
1925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 int save_errno = 0;
1927 if (self->kqfd >= 0) {
1928 int kqfd = self->kqfd;
1929 self->kqfd = -1;
1930 Py_BEGIN_ALLOW_THREADS
1931 if (close(kqfd) < 0)
1932 save_errno = errno;
1933 Py_END_ALLOW_THREADS
1934 }
1935 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001936}
1937
1938static PyObject *
1939newKqueue_Object(PyTypeObject *type, SOCKET fd)
1940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001942 assert(type != NULL);
1943 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1944 assert(queue_alloc != NULL);
1945 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 if (self == NULL) {
1947 return NULL;
1948 }
1949
1950 if (fd == -1) {
1951 Py_BEGIN_ALLOW_THREADS
1952 self->kqfd = kqueue();
1953 Py_END_ALLOW_THREADS
1954 }
1955 else {
1956 self->kqfd = fd;
1957 }
1958 if (self->kqfd < 0) {
1959 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001960 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 return NULL;
1962 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001963
1964 if (fd == -1) {
1965 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1966 Py_DECREF(self);
1967 return NULL;
1968 }
1969 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001971}
1972
Tal Einat6dc57e22018-06-30 23:02:48 +03001973/*[clinic input]
1974@classmethod
1975select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001976
Tal Einat6dc57e22018-06-30 23:02:48 +03001977Kqueue syscall wrapper.
1978
1979For example, to start watching a socket for input:
1980>>> kq = kqueue()
1981>>> sock = socket()
1982>>> sock.connect((host, port))
1983>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1984
1985To wait one second for it to become writeable:
1986>>> kq.control(None, 1, 1000)
1987
1988To stop listening:
1989>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1990[clinic start generated code]*/
1991
1992static PyObject *
1993select_kqueue_impl(PyTypeObject *type)
1994/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1995{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001997}
1998
1999static void
2000kqueue_queue_dealloc(kqueue_queue_Object *self)
2001{
Dino Viehlandf9190542019-09-14 15:20:27 +01002002 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002004 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2005 kqueue_free((PyObject *)self);
2006 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002007}
2008
Tal Einat6dc57e22018-06-30 23:02:48 +03002009/*[clinic input]
2010select.kqueue.close
2011
2012Close the kqueue control file descriptor.
2013
2014Further operations on the kqueue object will raise an exception.
2015[clinic start generated code]*/
2016
2017static PyObject *
2018select_kqueue_close_impl(kqueue_queue_Object *self)
2019/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 errno = kqueue_queue_internal_close(self);
2022 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002023 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 return NULL;
2025 }
2026 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002027}
2028
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002029static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002030kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 if (self->kqfd < 0)
2033 Py_RETURN_TRUE;
2034 else
2035 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002036}
2037
Tal Einat6dc57e22018-06-30 23:02:48 +03002038/*[clinic input]
2039select.kqueue.fileno
2040
2041Return the kqueue control file descriptor.
2042[clinic start generated code]*/
2043
2044static PyObject *
2045select_kqueue_fileno_impl(kqueue_queue_Object *self)
2046/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 if (self->kqfd < 0)
2049 return kqueue_queue_err_closed();
2050 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002051}
2052
Tal Einat6dc57e22018-06-30 23:02:48 +03002053/*[clinic input]
2054@classmethod
2055select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002056
Tal Einat6dc57e22018-06-30 23:02:48 +03002057 fd: int
2058 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002059
Tal Einat6dc57e22018-06-30 23:02:48 +03002060Create a kqueue object from a given control fd.
2061[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002062
2063static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002064select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2065/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002066{
Tal Einat6dc57e22018-06-30 23:02:48 +03002067 SOCKET s_fd = (SOCKET)fd;
2068
2069 return newKqueue_Object(type, s_fd);
2070}
2071
2072/*[clinic input]
2073select.kqueue.control
2074
2075 changelist: object
2076 Must be an iterable of kevent objects describing the changes to be made
2077 to the kernel's watch list or None.
2078 maxevents: int
2079 The maximum number of events that the kernel will return.
2080 timeout as otimeout: object = None
2081 The maximum time to wait in seconds, or else None to wait forever.
2082 This accepts floats for smaller timeouts, too.
2083 /
2084
2085Calls the kernel kevent function.
2086[clinic start generated code]*/
2087
2088static PyObject *
2089select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2090 int maxevents, PyObject *otimeout)
2091/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 int gotevents = 0;
2094 int nchanges = 0;
2095 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002096 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 PyObject *result = NULL;
2098 struct kevent *evl = NULL;
2099 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002100 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002102 _PyTime_t timeout, deadline = 0;
Christian Heimesea97eba2020-11-21 20:29:26 +01002103 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 if (self->kqfd < 0)
2106 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002107
Tal Einat6dc57e22018-06-30 23:02:48 +03002108 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 PyErr_Format(PyExc_ValueError,
2110 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002111 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 return NULL;
2113 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002114
Tal Einat6dc57e22018-06-30 23:02:48 +03002115 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 ptimeoutspec = NULL;
2117 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002118 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002119 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002120 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002121 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002122 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002123 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002124 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002125 return NULL;
2126 }
2127
Victor Stinner4448c082015-03-31 11:48:34 +02002128 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002129 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002130
Victor Stinner4448c082015-03-31 11:48:34 +02002131 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 PyErr_SetString(PyExc_ValueError,
2133 "timeout must be positive or None");
2134 return NULL;
2135 }
Victor Stinner4448c082015-03-31 11:48:34 +02002136 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002138
Tal Einat6dc57e22018-06-30 23:02:48 +03002139 if (changelist != Py_None) {
2140 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002141 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 return NULL;
2143 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002144 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2145 PyErr_SetString(PyExc_OverflowError,
2146 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 goto error;
2148 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002149 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 chl = PyMem_New(struct kevent, nchanges);
2152 if (chl == NULL) {
2153 PyErr_NoMemory();
2154 goto error;
2155 }
Christian Heimesea97eba2020-11-21 20:29:26 +01002156 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Serhiy Storchakade072102017-10-12 22:17:46 +03002157 for (i = 0; i < nchanges; ++i) {
2158 ei = PySequence_Fast_GET_ITEM(seq, i);
Christian Heimesea97eba2020-11-21 20:29:26 +01002159 if (!kqueue_event_Check(ei, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 PyErr_SetString(PyExc_TypeError,
2161 "changelist must be an iterable of "
2162 "select.kevent objects");
2163 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002165 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002167 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002171 if (maxevents) {
2172 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 if (evl == NULL) {
2174 PyErr_NoMemory();
2175 goto error;
2176 }
2177 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002178
Victor Stinner4448c082015-03-31 11:48:34 +02002179 if (ptimeoutspec)
2180 deadline = _PyTime_GetMonotonicClock() + timeout;
2181
2182 do {
2183 Py_BEGIN_ALLOW_THREADS
2184 errno = 0;
2185 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002186 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002187 Py_END_ALLOW_THREADS
2188
2189 if (errno != EINTR)
2190 break;
2191
2192 /* kevent() was interrupted by a signal */
2193 if (PyErr_CheckSignals())
2194 goto error;
2195
2196 if (ptimeoutspec) {
2197 timeout = deadline - _PyTime_GetMonotonicClock();
2198 if (timeout < 0) {
2199 gotevents = 0;
2200 break;
2201 }
2202 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2203 goto error;
2204 /* retry kevent() with the recomputed timeout */
2205 }
2206 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 if (gotevents == -1) {
2209 PyErr_SetFromErrno(PyExc_OSError);
2210 goto error;
2211 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 result = PyList_New(gotevents);
2214 if (result == NULL) {
2215 goto error;
2216 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 for (i = 0; i < gotevents; i++) {
2219 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002220
Christian Heimesea97eba2020-11-21 20:29:26 +01002221 ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 if (ch == NULL) {
2223 goto error;
2224 }
2225 ch->e = evl[i];
2226 PyList_SET_ITEM(result, i, (PyObject *)ch);
2227 }
2228 PyMem_Free(chl);
2229 PyMem_Free(evl);
2230 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
2232 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 PyMem_Free(chl);
2234 PyMem_Free(evl);
2235 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002236 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002238}
2239
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002240static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 {"closed", (getter)kqueue_queue_get_closed, NULL,
2242 "True if the kqueue handler is closed"},
2243 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244};
2245
Tal Einat6dc57e22018-06-30 23:02:48 +03002246#endif /* HAVE_KQUEUE */
2247
2248
2249/* ************************************************************************ */
2250
2251#include "clinic/selectmodule.c.h"
2252
2253#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2254
2255static PyMethodDef poll_methods[] = {
2256 SELECT_POLL_REGISTER_METHODDEF
2257 SELECT_POLL_MODIFY_METHODDEF
2258 SELECT_POLL_UNREGISTER_METHODDEF
2259 SELECT_POLL_POLL_METHODDEF
2260 {NULL, NULL} /* sentinel */
2261};
2262
Dino Viehlandf9190542019-09-14 15:20:27 +01002263
2264static PyType_Slot poll_Type_slots[] = {
2265 {Py_tp_dealloc, poll_dealloc},
2266 {Py_tp_methods, poll_methods},
Dino Viehlandf9190542019-09-14 15:20:27 +01002267 {0, 0},
2268};
2269
2270static PyType_Spec poll_Type_spec = {
Erlend Egeberg Aasland387397f2021-04-30 15:49:17 +02002271 .name = "select.poll",
2272 .basicsize = sizeof(pollObject),
2273 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
2274 .slots = poll_Type_slots,
Tal Einat6dc57e22018-06-30 23:02:48 +03002275};
2276
2277#ifdef HAVE_SYS_DEVPOLL_H
2278
2279static PyMethodDef devpoll_methods[] = {
2280 SELECT_DEVPOLL_REGISTER_METHODDEF
2281 SELECT_DEVPOLL_MODIFY_METHODDEF
2282 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2283 SELECT_DEVPOLL_POLL_METHODDEF
2284 SELECT_DEVPOLL_CLOSE_METHODDEF
2285 SELECT_DEVPOLL_FILENO_METHODDEF
2286 {NULL, NULL} /* sentinel */
2287};
2288
Tal Einat6dc57e22018-06-30 23:02:48 +03002289#endif /* HAVE_SYS_DEVPOLL_H */
2290
2291#endif /* HAVE_POLL */
2292
2293#ifdef HAVE_EPOLL
2294
2295static PyMethodDef pyepoll_methods[] = {
2296 SELECT_EPOLL_FROMFD_METHODDEF
2297 SELECT_EPOLL_CLOSE_METHODDEF
2298 SELECT_EPOLL_FILENO_METHODDEF
2299 SELECT_EPOLL_MODIFY_METHODDEF
2300 SELECT_EPOLL_REGISTER_METHODDEF
2301 SELECT_EPOLL_UNREGISTER_METHODDEF
2302 SELECT_EPOLL_POLL_METHODDEF
2303 SELECT_EPOLL___ENTER___METHODDEF
2304 SELECT_EPOLL___EXIT___METHODDEF
2305 {NULL, NULL},
2306};
2307
Dino Viehlandf9190542019-09-14 15:20:27 +01002308static PyType_Slot pyEpoll_Type_slots[] = {
2309 {Py_tp_dealloc, pyepoll_dealloc},
2310 {Py_tp_doc, (void*)pyepoll_doc},
2311 {Py_tp_getattro, PyObject_GenericGetAttr},
2312 {Py_tp_getset, pyepoll_getsetlist},
2313 {Py_tp_methods, pyepoll_methods},
2314 {Py_tp_new, select_epoll},
2315 {0, 0},
2316};
2317
2318static PyType_Spec pyEpoll_Type_spec = {
2319 "select.epoll",
2320 sizeof(pyEpoll_Object),
2321 0,
2322 Py_TPFLAGS_DEFAULT,
2323 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002324};
2325
2326#endif /* HAVE_EPOLL */
2327
2328#ifdef HAVE_KQUEUE
2329
Tal Einat6dc57e22018-06-30 23:02:48 +03002330static PyMethodDef kqueue_queue_methods[] = {
2331 SELECT_KQUEUE_FROMFD_METHODDEF
2332 SELECT_KQUEUE_CLOSE_METHODDEF
2333 SELECT_KQUEUE_FILENO_METHODDEF
2334 SELECT_KQUEUE_CONTROL_METHODDEF
2335 {NULL, NULL},
2336};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002337
Dino Viehlandf9190542019-09-14 15:20:27 +01002338static PyType_Slot kqueue_queue_Type_slots[] = {
2339 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002340 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002341 {Py_tp_getset, kqueue_queue_getsetlist},
2342 {Py_tp_methods, kqueue_queue_methods},
2343 {Py_tp_new, select_kqueue},
2344 {0, 0},
2345};
2346
2347static PyType_Spec kqueue_queue_Type_spec = {
2348 "select.kqueue",
2349 sizeof(kqueue_queue_Object),
2350 0,
2351 Py_TPFLAGS_DEFAULT,
2352 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002353};
2354
2355#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002356
2357
2358
2359
2360
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002361/* ************************************************************************ */
2362
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002363
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002364static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002365 SELECT_SELECT_METHODDEF
2366 SELECT_POLL_METHODDEF
2367 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002369};
2370
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002371PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002372"This module supports asynchronous I/O on multiple file descriptors.\n\
2373\n\
2374*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002375On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002376
Martin v. Löwis1a214512008-06-11 05:26:20 +00002377
Dino Viehlandf9190542019-09-14 15:20:27 +01002378
2379static int
2380_select_traverse(PyObject *module, visitproc visit, void *arg)
2381{
Christian Heimesea97eba2020-11-21 20:29:26 +01002382 _selectstate *state = get_select_state(module);
2383
2384 Py_VISIT(state->close);
2385 Py_VISIT(state->poll_Type);
2386 Py_VISIT(state->devpoll_Type);
2387 Py_VISIT(state->pyEpoll_Type);
2388 Py_VISIT(state->kqueue_event_Type);
2389 Py_VISIT(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002390 return 0;
2391}
2392
2393static int
2394_select_clear(PyObject *module)
2395{
Christian Heimesea97eba2020-11-21 20:29:26 +01002396 _selectstate *state = get_select_state(module);
2397
2398 Py_CLEAR(state->close);
2399 Py_CLEAR(state->poll_Type);
2400 Py_CLEAR(state->devpoll_Type);
2401 Py_CLEAR(state->pyEpoll_Type);
2402 Py_CLEAR(state->kqueue_event_Type);
2403 Py_CLEAR(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002404 return 0;
2405}
2406
2407static void
2408_select_free(void *module)
2409{
2410 _select_clear((PyObject *)module);
2411}
2412
Christian Heimesea97eba2020-11-21 20:29:26 +01002413int
2414_select_exec(PyObject *m)
Guido van Rossumed233a51992-06-23 09:07:03 +00002415{
Christian Heimesea97eba2020-11-21 20:29:26 +01002416 _selectstate *state = get_select_state(m);
Fred Drake4baedc12002-04-01 14:53:37 +00002417
Christian Heimesea97eba2020-11-21 20:29:26 +01002418 state->close = PyUnicode_InternFromString("close");
2419 if (state->close == NULL) {
2420 return -1;
2421 }
2422 if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
2423 return -1;
2424 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002425
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002426#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002427#ifdef HAVE_BROKEN_PIPE_BUF
2428#undef PIPE_BUF
2429#define PIPE_BUF 512
2430#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002431 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002432#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002433
Charles-François Natali986a56c2013-01-19 12:19:10 +01002434#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002435#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 if (select_have_broken_poll()) {
2437 if (PyObject_DelAttrString(m, "poll") == -1) {
2438 PyErr_Clear();
2439 }
2440 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002441#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002443#endif
Christian Heimesea97eba2020-11-21 20:29:26 +01002444 state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2445 m, &poll_Type_spec, NULL);
2446 if (state->poll_Type == NULL) {
2447 return -1;
2448 }
Dino Viehlandf9190542019-09-14 15:20:27 +01002449
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002450 PyModule_AddIntMacro(m, POLLIN);
2451 PyModule_AddIntMacro(m, POLLPRI);
2452 PyModule_AddIntMacro(m, POLLOUT);
2453 PyModule_AddIntMacro(m, POLLERR);
2454 PyModule_AddIntMacro(m, POLLHUP);
2455 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002456
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002457#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002458 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002459#endif
2460#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002461 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002462#endif
2463#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002464 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002465#endif
2466#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002467 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002468#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002469#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002470 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002471#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002472#ifdef POLLRDHUP
2473 /* Kernel 2.6.17+ */
2474 PyModule_AddIntMacro(m, POLLRDHUP);
2475#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002477#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002478
Jesus Cead8b9ae62011-11-14 19:07:41 +01002479#ifdef HAVE_SYS_DEVPOLL_H
Christian Heimesea97eba2020-11-21 20:29:26 +01002480 state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2481 m, &devpoll_Type_spec, NULL);
2482 if (state->devpoll_Type == NULL) {
2483 return -1;
2484 }
Jesus Cead8b9ae62011-11-14 19:07:41 +01002485#endif
2486
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002487#ifdef HAVE_EPOLL
Christian Heimesea97eba2020-11-21 20:29:26 +01002488 state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2489 m, &pyEpoll_Type_spec, NULL);
2490 if (state->pyEpoll_Type == NULL) {
2491 return -1;
2492 }
2493 if (PyModule_AddType(m, state->pyEpoll_Type) < 0) {
2494 return -1;
2495 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002496
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002497 PyModule_AddIntMacro(m, EPOLLIN);
2498 PyModule_AddIntMacro(m, EPOLLOUT);
2499 PyModule_AddIntMacro(m, EPOLLPRI);
2500 PyModule_AddIntMacro(m, EPOLLERR);
2501 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002502#ifdef EPOLLRDHUP
2503 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002504 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002505#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002506 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002507#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002509 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002510#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002511#ifdef EPOLLEXCLUSIVE
2512 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2513#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002514
2515#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002516 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002517#endif
2518#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002519 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002520#endif
2521#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002522 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002523#endif
2524#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002525 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002526#endif
2527#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002528 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002529#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002530
Benjamin Peterson95c16622011-12-27 15:36:32 -06002531#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002532 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002533#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002534#endif /* HAVE_EPOLL */
2535
2536#ifdef HAVE_KQUEUE
Christian Heimesea97eba2020-11-21 20:29:26 +01002537 state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2538 m, &kqueue_event_Type_spec, NULL);
2539 if (state->kqueue_event_Type == NULL) {
2540 return -1;
2541 }
2542 if (PyModule_AddType(m, state->kqueue_event_Type) < 0) {
2543 return -1;
2544 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002545
Christian Heimesea97eba2020-11-21 20:29:26 +01002546 state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2547 m, &kqueue_queue_Type_spec, NULL);
2548 if (state->kqueue_queue_Type == NULL) {
2549 return -1;
2550 }
2551 if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) {
2552 return -1;
2553 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002554
2555 /* event filters */
2556 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2557 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002558#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002559 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002560#endif
2561#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002562 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002563#endif
2564#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002566#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002567#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002569#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002570#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002572#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 /* event flags */
2576 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2577 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2578 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2579 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2580 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2581 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002582
Berker Peksag7ec64562016-09-14 18:16:59 +03002583#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002585#endif
2586#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002588#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2591 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002594#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002596#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002599#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2601 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2602 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2604 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2605 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2606 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002607#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002610#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2612 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2613 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2615 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2618 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2619 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621
2622 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002623#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2625 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2626 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002627#endif
2628
2629#endif /* HAVE_KQUEUE */
Christian Heimesea97eba2020-11-21 20:29:26 +01002630 return 0;
2631}
2632
2633static PyModuleDef_Slot _select_slots[] = {
2634 {Py_mod_exec, _select_exec},
2635 {0, NULL}
2636};
2637
2638static struct PyModuleDef selectmodule = {
2639 PyModuleDef_HEAD_INIT,
2640 .m_name = "select",
2641 .m_doc = module_doc,
2642 .m_size = sizeof(_selectstate),
2643 .m_methods = select_methods,
2644 .m_slots = _select_slots,
2645 .m_traverse = _select_traverse,
2646 .m_clear = _select_clear,
2647 .m_free = _select_free,
2648};
2649
2650PyMODINIT_FUNC
2651PyInit_select(void)
2652{
2653 return PyModuleDef_Init(&selectmodule);
Guido van Rossumed233a51992-06-23 09:07:03 +00002654}