blob: 3ecd0c32b3038948c081d7eb6d63d617c72059d6 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Berker Peksagfe8d9662016-07-19 21:09:26 +03007#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
8#define _GNU_SOURCE
9#endif
10
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000011#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020012#include "structmember.h" // PyMemberDef
Guido van Rossumed233a51992-06-23 09:07:03 +000013
Jesus Cead8b9ae62011-11-14 19:07:41 +010014#ifdef HAVE_SYS_DEVPOLL_H
15#include <sys/resource.h>
16#include <sys/devpoll.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#endif
21
Thomas Wouters477c8d52006-05-27 19:21:47 +000022#ifdef __APPLE__
23 /* Perform runtime testing for a broken poll on OSX to make it easier
24 * to use the same binary on multiple releases of the OS.
25 */
26#undef HAVE_BROKEN_POLL
27#endif
28
Tim Petersd92dfe02000-12-12 01:18:41 +000029/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
30 64 is too small (too many people have bumped into that limit).
31 Here we boost it.
32 Users who want even more than the boosted limit should #define
33 FD_SETSIZE higher before this; e.g., via compiler /D switch.
34*/
35#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
36#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000038
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000039#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000040#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000041#elif defined(HAVE_SYS_POLL_H)
42#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000043#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000044
Guido van Rossum37273171996-12-09 18:47:43 +000045#ifdef __sgi
46/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000047extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000048#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000052#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053
Guido van Rossum6f489d91996-06-28 20:15:15 +000054#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000055# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000057#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000059#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000060
Dino Viehlandf9190542019-09-14 15:20:27 +010061typedef struct {
62 PyObject *close;
63 PyTypeObject *poll_Type;
64 PyTypeObject *devpoll_Type;
65 PyTypeObject *pyEpoll_Type;
66 PyTypeObject *kqueue_event_Type;
67 PyTypeObject *kqueue_queue_Type;
68} _selectstate;
69
70static struct PyModuleDef selectmodule;
71
Hai Shif707d942020-03-16 21:15:01 +080072static inline _selectstate*
73get_select_state(PyObject *module)
74{
75 void *state = PyModule_GetState(module);
76 assert(state != NULL);
77 return (_selectstate *)state;
78}
79
Christian Heimesea97eba2020-11-21 20:29:26 +010080#define _selectstate_by_type(type) get_select_state(PyType_GetModule(type))
Dino Viehlandf9190542019-09-14 15:20:27 +010081
Tal Einat6dc57e22018-06-30 23:02:48 +030082/*[clinic input]
83module select
Christian Heimesea97eba2020-11-21 20:29:26 +010084class select.poll "pollObject *" "_selectstate_by_type(type)->poll_Type"
85class select.devpoll "devpollObject *" "_selectstate_by_type(type)->devpoll_Type"
86class select.epoll "pyEpoll_Object *" "_selectstate_by_type(type)->pyEpoll_Type"
87class select.kqueue "kqueue_queue_Object *" "_selectstate_by_type(type)->kqueue_queue_Type"
Tal Einat6dc57e22018-06-30 23:02:48 +030088[clinic start generated code]*/
Christian Heimesea97eba2020-11-21 20:29:26 +010089/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8072de35824aa327]*/
Tal Einat6dc57e22018-06-30 23:02:48 +030090
Barry Warsawc1cb3601996-12-12 22:16:21 +000091/* list of Python objects and their file descriptor */
92typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 PyObject *obj; /* owned reference */
94 SOCKET fd;
95 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000096} pylist;
97
Barry Warsawc1cb3601996-12-12 22:16:21 +000098static void
Tim Peters4b046c22001-08-16 21:59:46 +000099reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +0000100{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200101 unsigned int i;
102 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200103 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 }
105 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000106}
107
108
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000109/* returns -1 and sets the Python exception if an error occurred, otherwise
110 returns a number >= 0
111*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000112static int
Brett Cannon62dba4c2003-09-10 19:37:42 +0000113seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200116 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100117 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 PyObject* fast_seq = NULL;
119 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +0000120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
122 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Benjamin Petersone0edb8b2010-06-27 23:49:45 +0000124 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 if (!fast_seq)
126 return -1;
127
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100128 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 SOCKET v;
130
131 /* any intervening fileno() calls could decr this refcnt */
132 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200133 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 Py_INCREF(o);
136 v = PyObject_AsFileDescriptor( o );
137 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000138
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000139#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000141#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200142 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 PyErr_SetString(PyExc_ValueError,
144 "filedescriptor out of range in select()");
145 goto finally;
146 }
147 if (v > max)
148 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000149#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200153 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 PyErr_SetString(PyExc_ValueError,
155 "too many file descriptors in select()");
156 goto finally;
157 }
158 fd2obj[index].obj = o;
159 fd2obj[index].fd = v;
160 fd2obj[index].sentinel = 0;
161 fd2obj[++index].sentinel = -1;
162 }
163 Py_DECREF(fast_seq);
164 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000165
166 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 Py_XDECREF(o);
168 Py_DECREF(fast_seq);
169 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000170}
171
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000172/* returns NULL and sets the Python exception if an error occurred */
173static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000174set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 int i, j, count=0;
177 PyObject *list, *o;
178 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
181 if (FD_ISSET(fd2obj[j].fd, set))
182 count++;
183 }
184 list = PyList_New(count);
185 if (!list)
186 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 i = 0;
189 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
190 fd = fd2obj[j].fd;
191 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 o = fd2obj[j].obj;
193 fd2obj[j].obj = NULL;
194 /* transfer ownership */
195 if (PyList_SetItem(list, i, o) < 0)
196 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 i++;
199 }
200 }
201 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000202 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 Py_DECREF(list);
204 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000205}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000206
Barry Warsawb44740f2001-08-16 16:52:59 +0000207#undef SELECT_USES_HEAP
208#if FD_SETSIZE > 1024
209#define SELECT_USES_HEAP
210#endif /* FD_SETSIZE > 1024 */
211
Tal Einat6dc57e22018-06-30 23:02:48 +0300212/*[clinic input]
213select.select
214
215 rlist: object
216 wlist: object
217 xlist: object
218 timeout as timeout_obj: object = None
219 /
220
221Wait until one or more file descriptors are ready for some kind of I/O.
222
Jakub Stasiak372ee272020-05-25 09:03:48 +0200223The first three arguments are iterables of file descriptors to be waited for:
Tal Einat6dc57e22018-06-30 23:02:48 +0300224rlist -- wait until ready for reading
225wlist -- wait until ready for writing
226xlist -- wait for an "exceptional condition"
227If only one kind of condition is required, pass [] for the other lists.
228
229A file descriptor is either a socket or file object, or a small integer
230gotten from a fileno() method call on one of those.
231
232The optional 4th argument specifies a timeout in seconds; it may be
233a floating point number to specify fractions of seconds. If it is absent
234or None, the call will never time out.
235
236The return value is a tuple of three lists corresponding to the first three
237arguments; each contains the subset of the corresponding file descriptors
238that are ready.
239
240*** IMPORTANT NOTICE ***
241On Windows, only sockets are supported; on Unix, all file
242descriptors can be used.
243[clinic start generated code]*/
244
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000245static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300246select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
247 PyObject *xlist, PyObject *timeout_obj)
Jakub Stasiak372ee272020-05-25 09:03:48 +0200248/*[clinic end generated code: output=2b3cfa824f7ae4cf input=e467f5d68033de00]*/
Guido van Rossumed233a51992-06-23 09:07:03 +0000249{
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000252#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 /* XXX: All this should probably be implemented as follows:
254 * - find the highest descriptor we're interested in
255 * - add one
256 * - that's the size
257 * See: Stevens, APitUE, $12.5.1
258 */
259 pylist rfd2obj[FD_SETSIZE + 1];
260 pylist wfd2obj[FD_SETSIZE + 1];
261 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000262#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 PyObject *ret = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 int imax, omax, emax, max;
267 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200268 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000269
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200270 if (timeout_obj == Py_None)
271 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200273 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100274 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200275 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
276 PyErr_SetString(PyExc_TypeError,
277 "timeout must be a float or None");
278 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100279 return NULL;
280 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100281
Pablo Galindo2c15b292017-10-17 15:14:41 +0100282 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100283 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100284 if (tv.tv_sec < 0) {
285 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 return NULL;
287 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 tvp = &tv;
289 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000290
Barry Warsawb44740f2001-08-16 16:52:59 +0000291#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 /* Allocate memory for the lists */
293 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
294 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
295 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
296 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +0100297 if (rfd2obj) PyMem_Free(rfd2obj);
298 if (wfd2obj) PyMem_Free(wfd2obj);
299 if (efd2obj) PyMem_Free(efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return PyErr_NoMemory();
301 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000302#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200303
Jakub Stasiak372ee272020-05-25 09:03:48 +0200304 /* Convert iterables to fd_sets, and get maximum fd number
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 * propagates the Python exception set in seq2set()
306 */
307 rfd2obj[0].sentinel = -1;
308 wfd2obj[0].sentinel = -1;
309 efd2obj[0].sentinel = -1;
Tal Einat6dc57e22018-06-30 23:02:48 +0300310 if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300312 if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300314 if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 max = imax;
318 if (omax > max) max = omax;
319 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000320
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200321 if (tvp)
322 deadline = _PyTime_GetMonotonicClock() + timeout;
323
324 do {
325 Py_BEGIN_ALLOW_THREADS
326 errno = 0;
327 n = select(max, &ifdset, &ofdset, &efdset, tvp);
328 Py_END_ALLOW_THREADS
329
330 if (errno != EINTR)
331 break;
332
333 /* select() was interrupted by a signal */
334 if (PyErr_CheckSignals())
335 goto finally;
336
337 if (tvp) {
338 timeout = deadline - _PyTime_GetMonotonicClock();
339 if (timeout < 0) {
Oran Avraham7f524152018-12-05 22:36:03 +0200340 /* bpo-35310: lists were unmodified -- clear them explicitly */
341 FD_ZERO(&ifdset);
342 FD_ZERO(&ofdset);
343 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200344 n = 0;
345 break;
346 }
347 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200348 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200349 }
350 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000351
Thomas Heller106f4c72002-09-24 16:51:00 +0000352#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200354 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000356#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200358 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000360#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 else {
362 /* any of these three calls can raise an exception. it's more
363 convenient to test for this after all three calls... but
364 is that acceptable?
365 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300366 rlist = set2list(&ifdset, rfd2obj);
367 wlist = set2list(&ofdset, wfd2obj);
368 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 if (PyErr_Occurred())
370 ret = NULL;
371 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300372 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000373
Tal Einat6dc57e22018-06-30 23:02:48 +0300374 Py_XDECREF(rlist);
375 Py_XDECREF(wlist);
376 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 }
378
Barry Warsawc1cb3601996-12-12 22:16:21 +0000379 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 reap_obj(rfd2obj);
381 reap_obj(wfd2obj);
382 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000383#ifdef SELECT_USES_HEAP
Victor Stinner00d7abd2020-12-01 09:56:42 +0100384 PyMem_Free(rfd2obj);
385 PyMem_Free(wfd2obj);
386 PyMem_Free(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000387#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000389}
390
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000391#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000393 * poll() support
394 */
395
396typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 PyObject_HEAD
398 PyObject *dict;
399 int ufd_uptodate;
400 int ufd_len;
401 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300402 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000403} pollObject;
404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000406 contained within a pollObject. Return 1 on success, 0 on an error.
407*/
408
409static int
410update_ufd_array(pollObject *self)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 Py_ssize_t i, pos;
413 PyObject *key, *value;
414 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000415
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200416 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
418 if (self->ufds == NULL) {
419 self->ufds = old_ufds;
420 PyErr_NoMemory();
421 return 0;
422 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 i = pos = 0;
425 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200426 assert(i < self->ufd_len);
427 /* Never overflow */
428 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200429 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 i++;
431 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200432 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 self->ufd_uptodate = 1;
434 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Tal Einat6dc57e22018-06-30 23:02:48 +0300437/*[clinic input]
438select.poll.register
439
440 fd: fildes
441 either an integer, or an object with a fileno() method returning an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700442 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300443 an optional bitmask describing the type of events to check for
444 /
445
446Register a file descriptor with the polling object.
447[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448
449static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300450select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700451/*[clinic end generated code: output=0dc7173c800a4a65 input=34e16cfb28d3c900]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452{
Tal Einat6dc57e22018-06-30 23:02:48 +0300453 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 /* Add entry to the internal dictionary: the key is the
457 file descriptor, and the value is the event mask. */
458 key = PyLong_FromLong(fd);
459 if (key == NULL)
460 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300461 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 if (value == NULL) {
463 Py_DECREF(key);
464 return NULL;
465 }
466 err = PyDict_SetItem(self->dict, key, value);
467 Py_DECREF(key);
468 Py_DECREF(value);
469 if (err < 0)
470 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 self->ufd_uptodate = 0;
473
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200474 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000475}
476
Tal Einat6dc57e22018-06-30 23:02:48 +0300477
478/*[clinic input]
479select.poll.modify
480
481 fd: fildes
482 either an integer, or an object with a fileno() method returning
483 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300484 eventmask: unsigned_short
Tal Einat6dc57e22018-06-30 23:02:48 +0300485 a bitmask describing the type of events to check for
486 /
487
488Modify an already registered file descriptor.
489[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000490
491static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300492select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300493/*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000494{
Tal Einat6dc57e22018-06-30 23:02:48 +0300495 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 /* Modify registered fd */
499 key = PyLong_FromLong(fd);
500 if (key == NULL)
501 return NULL;
Serhiy Storchakab510e102020-10-26 12:47:57 +0200502 err = PyDict_Contains(self->dict, key);
503 if (err < 0) {
504 Py_DECREF(key);
505 return NULL;
506 }
507 if (err == 0) {
508 errno = ENOENT;
509 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200510 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return NULL;
512 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300513 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 if (value == NULL) {
515 Py_DECREF(key);
516 return NULL;
517 }
518 err = PyDict_SetItem(self->dict, key, value);
519 Py_DECREF(key);
520 Py_DECREF(value);
521 if (err < 0)
522 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 self->ufd_uptodate = 0;
525
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200526 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000527}
528
529
Tal Einat6dc57e22018-06-30 23:02:48 +0300530/*[clinic input]
531select.poll.unregister
532
533 fd: fildes
534 /
535
536Remove a file descriptor being tracked by the polling object.
537[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000538
539static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300540select_poll_unregister_impl(pollObject *self, int fd)
541/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 /* Check whether the fd is already in the array */
546 key = PyLong_FromLong(fd);
547 if (key == NULL)
548 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 if (PyDict_DelItem(self->dict, key) == -1) {
551 Py_DECREF(key);
552 /* This will simply raise the KeyError set by PyDict_DelItem
553 if the file descriptor isn't registered. */
554 return NULL;
555 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 Py_DECREF(key);
558 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000559
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200560 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000561}
562
Tal Einat6dc57e22018-06-30 23:02:48 +0300563/*[clinic input]
564select.poll.poll
565
566 timeout as timeout_obj: object = None
567 /
568
569Polls the set of registered file descriptors.
570
571Returns a list containing any descriptors that have events or errors to
572report, as a list of (fd, event) 2-tuples.
573[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000574
575static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300576select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
577/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000578{
Tal Einat6dc57e22018-06-30 23:02:48 +0300579 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200580 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200582 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584
Tal Einat6dc57e22018-06-30 23:02:48 +0300585 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200586 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100587 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200588 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
589 PyErr_SetString(PyExc_TypeError,
590 "timeout must be an integer or None");
591 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200593 }
594
Pablo Galindo2c15b292017-10-17 15:14:41 +0100595 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200596 if (ms < INT_MIN || ms > INT_MAX) {
597 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200599 }
600
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200601 if (timeout >= 0) {
602 deadline = _PyTime_GetMonotonicClock() + timeout;
603 }
604 }
605
606 /* On some OSes, typically BSD-based ones, the timeout parameter of the
607 poll() syscall, when negative, must be exactly INFTIM, where defined,
608 or -1. See issue 31334. */
609 if (ms < 0) {
610#ifdef INFTIM
611 ms = INFTIM;
612#else
613 ms = -1;
614#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000616
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300617 /* Avoid concurrent poll() invocation, issue 8865 */
618 if (self->poll_running) {
619 PyErr_SetString(PyExc_RuntimeError,
620 "concurrent poll() invocation");
621 return NULL;
622 }
623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 /* Ensure the ufd array is up to date */
625 if (!self->ufd_uptodate)
626 if (update_ufd_array(self) == 0)
627 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300629 self->poll_running = 1;
630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200632 async_err = 0;
633 do {
634 Py_BEGIN_ALLOW_THREADS
635 errno = 0;
636 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
637 Py_END_ALLOW_THREADS
638
639 if (errno != EINTR)
640 break;
641
642 /* poll() was interrupted by a signal */
643 if (PyErr_CheckSignals()) {
644 async_err = 1;
645 break;
646 }
647
648 if (timeout >= 0) {
649 timeout = deadline - _PyTime_GetMonotonicClock();
650 if (timeout < 0) {
651 poll_result = 0;
652 break;
653 }
654 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
655 /* retry poll() with the recomputed timeout */
656 }
657 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300659 self->poll_running = 0;
660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200662 if (!async_err)
663 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 return NULL;
665 }
666
667 /* build the result list */
668
669 result_list = PyList_New(poll_result);
670 if (!result_list)
671 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200673 for (i = 0, j = 0; j < poll_result; j++) {
674 /* skip to the next fired descriptor */
675 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 i++;
677 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200678 /* if we hit a NULL return, set value to NULL
679 and break out of loop; code at end will
680 clean up result_list */
681 value = PyTuple_New(2);
682 if (value == NULL)
683 goto error;
684 num = PyLong_FromLong(self->ufds[i].fd);
685 if (num == NULL) {
686 Py_DECREF(value);
687 goto error;
688 }
689 PyTuple_SET_ITEM(value, 0, num);
690
691 /* The &0xffff is a workaround for AIX. 'revents'
692 is a 16-bit short, and IBM assigned POLLNVAL
693 to be 0x8000, so the conversion to int results
694 in a negative number. See SF bug #923315. */
695 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
696 if (num == NULL) {
697 Py_DECREF(value);
698 goto error;
699 }
700 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700701 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200702 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 }
704 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000705
706 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 Py_DECREF(result_list);
708 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000709}
710
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000711static pollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +0100712newPollObject(PyObject *module)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 pollObject *self;
Christian Heimesea97eba2020-11-21 20:29:26 +0100715 self = PyObject_New(pollObject, get_select_state(module)->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 if (self == NULL)
717 return NULL;
718 /* ufd_uptodate is a Boolean, denoting whether the
719 array pointed to by ufds matches the contents of the dictionary. */
720 self->ufd_uptodate = 0;
721 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300722 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 self->dict = PyDict_New();
724 if (self->dict == NULL) {
725 Py_DECREF(self);
726 return NULL;
727 }
728 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000729}
730
731static void
732poll_dealloc(pollObject *self)
733{
Dino Viehlandf9190542019-09-14 15:20:27 +0100734 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 if (self->ufds != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100736 PyMem_Free(self->ufds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 Py_XDECREF(self->dict);
Victor Stinner32bd68c2020-12-01 10:37:39 +0100738 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100739 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000740}
741
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000742
Jesus Cead8b9ae62011-11-14 19:07:41 +0100743#ifdef HAVE_SYS_DEVPOLL_H
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300744static PyMethodDef devpoll_methods[];
745
Jesus Cead8b9ae62011-11-14 19:07:41 +0100746typedef struct {
747 PyObject_HEAD
748 int fd_devpoll;
749 int max_n_fds;
750 int n_fds;
751 struct pollfd *fds;
752} devpollObject;
753
Victor Stinner13423c32013-08-22 00:19:50 +0200754static PyObject *
755devpoll_err_closed(void)
756{
757 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
758 return NULL;
759}
760
Jesus Cead8b9ae62011-11-14 19:07:41 +0100761static int devpoll_flush(devpollObject *self)
762{
763 int size, n;
764
765 if (!self->n_fds) return 0;
766
767 size = sizeof(struct pollfd)*self->n_fds;
768 self->n_fds = 0;
769
Victor Stinner54799672015-03-19 23:33:09 +0100770 n = _Py_write(self->fd_devpoll, self->fds, size);
771 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100772 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100773
Jesus Cead8b9ae62011-11-14 19:07:41 +0100774 if (n < size) {
775 /*
776 ** Data writed to /dev/poll is a binary data structure. It is not
777 ** clear what to do if a partial write occurred. For now, raise
778 ** an exception and see if we actually found this problem in
779 ** the wild.
780 ** See http://bugs.python.org/issue6397.
781 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300782 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100783 "Please, report at http://bugs.python.org/. "
784 "Data to report: Size tried: %d, actual size written: %d.",
785 size, n);
786 return -1;
787 }
788 return 0;
789}
790
791static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300792internal_devpoll_register(devpollObject *self, int fd,
793 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100794{
Victor Stinner13423c32013-08-22 00:19:50 +0200795 if (self->fd_devpoll < 0)
796 return devpoll_err_closed();
797
Jesus Cead8b9ae62011-11-14 19:07:41 +0100798 if (remove) {
799 self->fds[self->n_fds].fd = fd;
800 self->fds[self->n_fds].events = POLLREMOVE;
801
802 if (++self->n_fds == self->max_n_fds) {
803 if (devpoll_flush(self))
804 return NULL;
805 }
806 }
807
808 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200809 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100810
811 if (++self->n_fds == self->max_n_fds) {
812 if (devpoll_flush(self))
813 return NULL;
814 }
815
816 Py_RETURN_NONE;
817}
818
Tal Einat6dc57e22018-06-30 23:02:48 +0300819/*[clinic input]
820select.devpoll.register
821
822 fd: fildes
823 either an integer, or an object with a fileno() method returning
824 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700825 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300826 an optional bitmask describing the type of events to check for
827 /
828
829Register a file descriptor with the polling object.
830[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100831
832static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300833select_devpoll_register_impl(devpollObject *self, int fd,
834 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700835/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100836{
Tal Einat6dc57e22018-06-30 23:02:48 +0300837 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100838}
839
Tal Einat6dc57e22018-06-30 23:02:48 +0300840/*[clinic input]
841select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100842
Tal Einat6dc57e22018-06-30 23:02:48 +0300843 fd: fildes
844 either an integer, or an object with a fileno() method returning
845 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700846 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300847 an optional bitmask describing the type of events to check for
848 /
849
850Modify a possible already registered file descriptor.
851[clinic start generated code]*/
852
853static PyObject *
854select_devpoll_modify_impl(devpollObject *self, int fd,
855 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700856/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100857{
Tal Einat6dc57e22018-06-30 23:02:48 +0300858 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859}
860
Tal Einat6dc57e22018-06-30 23:02:48 +0300861/*[clinic input]
862select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863
Tal Einat6dc57e22018-06-30 23:02:48 +0300864 fd: fildes
865 /
866
867Remove a file descriptor being tracked by the polling object.
868[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100869
870static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300871select_devpoll_unregister_impl(devpollObject *self, int fd)
872/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100873{
Victor Stinner13423c32013-08-22 00:19:50 +0200874 if (self->fd_devpoll < 0)
875 return devpoll_err_closed();
876
Jesus Cead8b9ae62011-11-14 19:07:41 +0100877 self->fds[self->n_fds].fd = fd;
878 self->fds[self->n_fds].events = POLLREMOVE;
879
880 if (++self->n_fds == self->max_n_fds) {
881 if (devpoll_flush(self))
882 return NULL;
883 }
884
885 Py_RETURN_NONE;
886}
887
Tal Einat6dc57e22018-06-30 23:02:48 +0300888/*[clinic input]
889select.devpoll.poll
890 timeout as timeout_obj: object = None
891 /
892
893Polls the set of registered file descriptors.
894
895Returns a list containing any descriptors that have events or errors to
896report, as a list of (fd, event) 2-tuples.
897[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100898
899static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300900select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
901/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902{
903 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200904 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100905 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100906 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200907 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100908
Victor Stinner13423c32013-08-22 00:19:50 +0200909 if (self->fd_devpoll < 0)
910 return devpoll_err_closed();
911
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300913 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100914 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200915 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100916 }
917 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200918 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100919 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200920 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
921 PyErr_SetString(PyExc_TypeError,
922 "timeout must be an integer or None");
923 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100924 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200925 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100926
Pablo Galindo2c15b292017-10-17 15:14:41 +0100927 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200928 if (ms < -1 || ms > INT_MAX) {
929 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
930 return NULL;
931 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100932 }
933
934 if (devpoll_flush(self))
935 return NULL;
936
937 dvp.dp_fds = self->fds;
938 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200939 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100940
Victor Stinner45ca48b2015-03-31 12:10:33 +0200941 if (timeout >= 0)
942 deadline = _PyTime_GetMonotonicClock() + timeout;
943
944 do {
945 /* call devpoll() */
946 Py_BEGIN_ALLOW_THREADS
947 errno = 0;
948 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
949 Py_END_ALLOW_THREADS
950
951 if (errno != EINTR)
952 break;
953
954 /* devpoll() was interrupted by a signal */
955 if (PyErr_CheckSignals())
956 return NULL;
957
958 if (timeout >= 0) {
959 timeout = deadline - _PyTime_GetMonotonicClock();
960 if (timeout < 0) {
961 poll_result = 0;
962 break;
963 }
964 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
965 dvp.dp_timeout = (int)ms;
966 /* retry devpoll() with the recomputed timeout */
967 }
968 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100969
970 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300971 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100972 return NULL;
973 }
974
975 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976 result_list = PyList_New(poll_result);
977 if (!result_list)
978 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200979
980 for (i = 0; i < poll_result; i++) {
981 num1 = PyLong_FromLong(self->fds[i].fd);
982 num2 = PyLong_FromLong(self->fds[i].revents);
983 if ((num1 == NULL) || (num2 == NULL)) {
984 Py_XDECREF(num1);
985 Py_XDECREF(num2);
986 goto error;
987 }
988 value = PyTuple_Pack(2, num1, num2);
989 Py_DECREF(num1);
990 Py_DECREF(num2);
991 if (value == NULL)
992 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -0700993 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100994 }
995
996 return result_list;
997
998 error:
999 Py_DECREF(result_list);
1000 return NULL;
1001}
1002
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001003static int
1004devpoll_internal_close(devpollObject *self)
1005{
1006 int save_errno = 0;
1007 if (self->fd_devpoll >= 0) {
1008 int fd = self->fd_devpoll;
1009 self->fd_devpoll = -1;
1010 Py_BEGIN_ALLOW_THREADS
1011 if (close(fd) < 0)
1012 save_errno = errno;
1013 Py_END_ALLOW_THREADS
1014 }
1015 return save_errno;
1016}
1017
Tal Einat6dc57e22018-06-30 23:02:48 +03001018/*[clinic input]
1019select.devpoll.close
1020
1021Close the devpoll file descriptor.
1022
1023Further operations on the devpoll object will raise an exception.
1024[clinic start generated code]*/
1025
1026static PyObject *
1027select_devpoll_close_impl(devpollObject *self)
1028/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001029{
1030 errno = devpoll_internal_close(self);
1031 if (errno < 0) {
1032 PyErr_SetFromErrno(PyExc_OSError);
1033 return NULL;
1034 }
1035 Py_RETURN_NONE;
1036}
1037
Victor Stinner13423c32013-08-22 00:19:50 +02001038static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001039devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001040{
1041 if (self->fd_devpoll < 0)
1042 Py_RETURN_TRUE;
1043 else
1044 Py_RETURN_FALSE;
1045}
1046
Tal Einat6dc57e22018-06-30 23:02:48 +03001047/*[clinic input]
1048select.devpoll.fileno
1049
1050Return the file descriptor.
1051[clinic start generated code]*/
1052
1053static PyObject *
1054select_devpoll_fileno_impl(devpollObject *self)
1055/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001056{
1057 if (self->fd_devpoll < 0)
1058 return devpoll_err_closed();
1059 return PyLong_FromLong(self->fd_devpoll);
1060}
1061
Victor Stinner13423c32013-08-22 00:19:50 +02001062static PyGetSetDef devpoll_getsetlist[] = {
1063 {"closed", (getter)devpoll_get_closed, NULL,
1064 "True if the devpoll object is closed"},
1065 {0},
1066};
1067
Jesus Cead8b9ae62011-11-14 19:07:41 +01001068static devpollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +01001069newDevPollObject(PyObject *module)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001070{
1071 devpollObject *self;
1072 int fd_devpoll, limit_result;
1073 struct pollfd *fds;
1074 struct rlimit limit;
1075
Jesus Cead8b9ae62011-11-14 19:07:41 +01001076 /*
1077 ** If we try to process more that getrlimit()
1078 ** fds, the kernel will give an error, so
1079 ** we set the limit here. It is a dynamic
1080 ** value, because we can change rlimit() anytime.
1081 */
1082 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083 if (limit_result == -1) {
1084 PyErr_SetFromErrno(PyExc_OSError);
1085 return NULL;
1086 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001087
1088 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1089 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001091
1092 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1093 if (fds == NULL) {
1094 close(fd_devpoll);
1095 PyErr_NoMemory();
1096 return NULL;
1097 }
1098
Christian Heimesea97eba2020-11-21 20:29:26 +01001099 self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001100 if (self == NULL) {
1101 close(fd_devpoll);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001102 PyMem_Free(fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001103 return NULL;
1104 }
1105 self->fd_devpoll = fd_devpoll;
1106 self->max_n_fds = limit.rlim_cur;
1107 self->n_fds = 0;
1108 self->fds = fds;
1109
1110 return self;
1111}
1112
1113static void
1114devpoll_dealloc(devpollObject *self)
1115{
Dino Viehlandf9190542019-09-14 15:20:27 +01001116 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001117 (void)devpoll_internal_close(self);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001118 PyMem_Free(self->fds);
Victor Stinner32bd68c2020-12-01 10:37:39 +01001119 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001120 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001121}
1122
Dino Viehlandf9190542019-09-14 15:20:27 +01001123static PyType_Slot devpoll_Type_slots[] = {
1124 {Py_tp_dealloc, devpoll_dealloc},
1125 {Py_tp_getset, devpoll_getsetlist},
1126 {Py_tp_methods, devpoll_methods},
Dino Viehlandf9190542019-09-14 15:20:27 +01001127 {0, 0},
1128};
1129
1130static PyType_Spec devpoll_Type_spec = {
1131 "select.devpoll",
1132 sizeof(devpollObject),
1133 0,
Victor Stinner7dcf0f62021-04-30 18:19:57 +02001134 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
Dino Viehlandf9190542019-09-14 15:20:27 +01001135 devpoll_Type_slots
1136};
1137
Jesus Cead8b9ae62011-11-14 19:07:41 +01001138#endif /* HAVE_SYS_DEVPOLL_H */
1139
1140
Tal Einat6dc57e22018-06-30 23:02:48 +03001141/*[clinic input]
1142select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001143
Tal Einat6dc57e22018-06-30 23:02:48 +03001144Returns a polling object.
1145
1146This object supports registering and unregistering file descriptors, and then
1147polling them for I/O events.
1148[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001149
1150static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001151select_poll_impl(PyObject *module)
1152/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001153{
Christian Heimesea97eba2020-11-21 20:29:26 +01001154 return (PyObject *)newPollObject(module);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001155}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001156
Jesus Cead8b9ae62011-11-14 19:07:41 +01001157#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001158
1159/*[clinic input]
1160select.devpoll
1161
1162Returns a polling object.
1163
1164This object supports registering and unregistering file descriptors, and then
1165polling them for I/O events.
1166[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001167
1168static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001169select_devpoll_impl(PyObject *module)
1170/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001171{
Christian Heimesea97eba2020-11-21 20:29:26 +01001172 return (PyObject *)newDevPollObject(module);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001173}
1174#endif
1175
1176
Thomas Wouters477c8d52006-05-27 19:21:47 +00001177#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001179 * On some systems poll() sets errno on invalid file descriptors. We test
1180 * for this at runtime because this bug may be fixed or introduced between
1181 * OS releases.
1182 */
1183static int select_have_broken_poll(void)
1184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 int poll_test;
1186 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 /* Create a file descriptor to make invalid */
1191 if (pipe(filedes) < 0) {
1192 return 1;
1193 }
1194 poll_struct.fd = filedes[0];
1195 close(filedes[0]);
1196 close(filedes[1]);
1197 poll_test = poll(&poll_struct, 1, 0);
1198 if (poll_test < 0) {
1199 return 1;
1200 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1201 return 1;
1202 }
1203 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204}
1205#endif /* __APPLE__ */
1206
1207#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001208
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001209#ifdef HAVE_EPOLL
1210/* **************************************************************************
1211 * epoll interface for Linux 2.6
1212 *
1213 * Written by Christian Heimes
1214 * Inspired by Twisted's _epoll.pyx and select.poll()
1215 */
1216
1217#ifdef HAVE_SYS_EPOLL_H
1218#include <sys/epoll.h>
1219#endif
1220
1221typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001223 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001224} pyEpoll_Object;
1225
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001226static PyObject *
1227pyepoll_err_closed(void)
1228{
Victor Stinner13423c32013-08-22 00:19:50 +02001229 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231}
1232
1233static int
1234pyepoll_internal_close(pyEpoll_Object *self)
1235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 int save_errno = 0;
1237 if (self->epfd >= 0) {
1238 int epfd = self->epfd;
1239 self->epfd = -1;
1240 Py_BEGIN_ALLOW_THREADS
1241 if (close(epfd) < 0)
1242 save_errno = errno;
1243 Py_END_ALLOW_THREADS
1244 }
1245 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001246}
1247
1248static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001249newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001252 assert(type != NULL);
1253 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1254 assert(epoll_alloc != NULL);
1255 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 if (self == NULL)
1257 return NULL;
1258
1259 if (fd == -1) {
1260 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001261#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001262 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1263#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001264 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001265#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 Py_END_ALLOW_THREADS
1267 }
1268 else {
1269 self->epfd = fd;
1270 }
1271 if (self->epfd < 0) {
1272 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001273 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 return NULL;
1275 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001276
1277#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001278 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001279 Py_DECREF(self);
1280 return NULL;
1281 }
1282#endif
1283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001285}
1286
1287
Tal Einat6dc57e22018-06-30 23:02:48 +03001288/*[clinic input]
1289@classmethod
1290select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001291
Tal Einat6dc57e22018-06-30 23:02:48 +03001292 sizehint: int = -1
1293 The expected number of events to be registered. It must be positive,
1294 or -1 to use the default. It is only used on older systems where
1295 epoll_create1() is not available; otherwise it has no effect (though its
1296 value is still checked).
1297 flags: int = 0
1298 Deprecated and completely ignored. However, when supplied, its value
1299 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1300
1301Returns an epolling object.
1302[clinic start generated code]*/
1303
1304static PyObject *
1305select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1306/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1307{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001308 if (sizehint == -1) {
1309 sizehint = FD_SETSIZE - 1;
1310 }
1311 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001312 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001313 return NULL;
1314 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001315
1316#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001317 if (flags && flags != EPOLL_CLOEXEC) {
1318 PyErr_SetString(PyExc_OSError, "invalid flags");
1319 return NULL;
1320 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001321#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001322
Berker Peksage2197d12016-09-26 23:30:41 +03001323 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001324}
1325
1326
1327static void
1328pyepoll_dealloc(pyEpoll_Object *self)
1329{
Dino Viehlandf9190542019-09-14 15:20:27 +01001330 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001332 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1333 epoll_free((PyObject *)self);
1334 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001335}
1336
Tal Einat6dc57e22018-06-30 23:02:48 +03001337/*[clinic input]
1338select.epoll.close
1339
1340Close the epoll control file descriptor.
1341
1342Further operations on the epoll object will raise an exception.
1343[clinic start generated code]*/
1344
1345static PyObject *
1346select_epoll_close_impl(pyEpoll_Object *self)
1347/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 errno = pyepoll_internal_close(self);
1350 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001351 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 return NULL;
1353 }
1354 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001355}
1356
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001357
1358static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001359pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 if (self->epfd < 0)
1362 Py_RETURN_TRUE;
1363 else
1364 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365}
1366
Tal Einat6dc57e22018-06-30 23:02:48 +03001367/*[clinic input]
1368select.epoll.fileno
1369
1370Return the epoll control file descriptor.
1371[clinic start generated code]*/
1372
1373static PyObject *
1374select_epoll_fileno_impl(pyEpoll_Object *self)
1375/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 if (self->epfd < 0)
1378 return pyepoll_err_closed();
1379 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380}
1381
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001382
Tal Einat6dc57e22018-06-30 23:02:48 +03001383/*[clinic input]
1384@classmethod
1385select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386
Tal Einat6dc57e22018-06-30 23:02:48 +03001387 fd: int
1388 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389
Tal Einat6dc57e22018-06-30 23:02:48 +03001390Create an epoll object from a given control fd.
1391[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001392
1393static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001394select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1395/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1396{
1397 SOCKET s_fd = (SOCKET)fd;
1398 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1399}
1400
1401
1402static PyObject *
1403pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 struct epoll_event ev;
1406 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 if (epfd < 0)
1409 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001410
Guido van Rossumee07b942013-12-06 17:46:22 -08001411 switch (op) {
1412 case EPOLL_CTL_ADD:
1413 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 ev.events = events;
1415 ev.data.fd = fd;
1416 Py_BEGIN_ALLOW_THREADS
1417 result = epoll_ctl(epfd, op, fd, &ev);
1418 Py_END_ALLOW_THREADS
1419 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001420 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1422 * operation required a non-NULL pointer in event, even
1423 * though this argument is ignored. */
1424 Py_BEGIN_ALLOW_THREADS
1425 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 Py_END_ALLOW_THREADS
1427 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001428 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 result = -1;
1430 errno = EINVAL;
1431 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001434 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 return NULL;
1436 }
1437 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001438}
1439
Tal Einat6dc57e22018-06-30 23:02:48 +03001440/*[clinic input]
1441select.epoll.register
1442
1443 fd: fildes
1444 the target file descriptor of the operation
Anthony Sottiled0518012020-06-23 14:49:56 -07001445 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001446 a bit set composed of the various EPOLL constants
1447
1448Registers a new fd or raises an OSError if the fd is already registered.
1449
1450The epoll interface supports all file descriptors that support poll.
1451[clinic start generated code]*/
1452
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001453static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001454select_epoll_register_impl(pyEpoll_Object *self, int fd,
1455 unsigned int eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -07001456/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001457{
Tal Einat6dc57e22018-06-30 23:02:48 +03001458 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001459}
1460
Tal Einat6dc57e22018-06-30 23:02:48 +03001461/*[clinic input]
1462select.epoll.modify
1463
1464 fd: fildes
1465 the target file descriptor of the operation
1466 eventmask: unsigned_int(bitwise=True)
1467 a bit set composed of the various EPOLL constants
1468
1469Modify event mask for a registered file descriptor.
1470[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471
1472static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001473select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1474 unsigned int eventmask)
1475/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476{
Tal Einat6dc57e22018-06-30 23:02:48 +03001477 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001478}
1479
Tal Einat6dc57e22018-06-30 23:02:48 +03001480/*[clinic input]
1481select.epoll.unregister
1482
1483 fd: fildes
1484 the target file descriptor of the operation
1485
1486Remove a registered file descriptor from the epoll object.
1487[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001488
1489static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001490select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1491/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001492{
Tal Einat6dc57e22018-06-30 23:02:48 +03001493 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001494}
1495
Tal Einat6dc57e22018-06-30 23:02:48 +03001496/*[clinic input]
1497select.epoll.poll
1498
1499 timeout as timeout_obj: object = None
1500 the maximum time to wait in seconds (as float);
1501 a timeout of None or -1 makes poll wait indefinitely
1502 maxevents: int = -1
1503 the maximum number of events returned; -1 means no limit
1504
1505Wait for events on the epoll file descriptor.
1506
1507Returns a list containing any descriptors that have events to report,
1508as a list of (fd, events) 2-tuples.
1509[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001510
1511static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001512select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1513 int maxevents)
1514/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 int nfds, i;
1517 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001518 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001519 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 if (self->epfd < 0)
1522 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001523
Berker Peksagb690b9b2018-09-11 20:29:48 +03001524 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001525 /* epoll_wait() has a resolution of 1 millisecond, round towards
1526 infinity to wait at least timeout seconds. */
1527 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001528 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001529 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1530 PyErr_SetString(PyExc_TypeError,
1531 "timeout must be an integer or None");
1532 }
1533 return NULL;
1534 }
1535
1536 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1537 if (ms < INT_MIN || ms > INT_MAX) {
1538 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1539 return NULL;
1540 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001541 /* epoll_wait(2) treats all arbitrary negative numbers the same
1542 for the timeout argument, but -1 is the documented way to block
1543 indefinitely in the epoll_wait(2) documentation, so we set ms
1544 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001545
Berker Peksagb690b9b2018-09-11 20:29:48 +03001546 Note that we didn't use INFTIM here since it's non-standard and
1547 isn't available under Linux. */
1548 if (ms < 0) {
1549 ms = -1;
1550 }
1551
1552 if (timeout >= 0) {
1553 deadline = _PyTime_GetMonotonicClock() + timeout;
1554 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001558 maxevents = FD_SETSIZE-1;
1559 }
1560 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 PyErr_Format(PyExc_ValueError,
1562 "maxevents must be greater than 0, got %d",
1563 maxevents);
1564 return NULL;
1565 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001566
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001567 evs = PyMem_New(struct epoll_event, maxevents);
1568 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001569 PyErr_NoMemory();
1570 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001572
Victor Stinner41eba222015-03-30 21:59:21 +02001573 do {
1574 Py_BEGIN_ALLOW_THREADS
1575 errno = 0;
1576 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1577 Py_END_ALLOW_THREADS
1578
1579 if (errno != EINTR)
1580 break;
1581
1582 /* poll() was interrupted by a signal */
1583 if (PyErr_CheckSignals())
1584 goto error;
1585
1586 if (timeout >= 0) {
1587 timeout = deadline - _PyTime_GetMonotonicClock();
1588 if (timeout < 0) {
1589 nfds = 0;
1590 break;
1591 }
1592 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1593 /* retry epoll_wait() with the recomputed timeout */
1594 }
1595 } while(1);
1596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001598 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 goto error;
1600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 elist = PyList_New(nfds);
1603 if (elist == NULL) {
1604 goto error;
1605 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001608 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 if (etuple == NULL) {
1610 Py_CLEAR(elist);
1611 goto error;
1612 }
1613 PyList_SET_ITEM(elist, i, etuple);
1614 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001615
Christian Heimesf6cd9672008-03-26 13:45:42 +00001616 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001617 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001619}
1620
Tal Einat6dc57e22018-06-30 23:02:48 +03001621
1622/*[clinic input]
1623select.epoll.__enter__
1624
1625[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001626
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001627static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001628select_epoll___enter___impl(pyEpoll_Object *self)
1629/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001630{
1631 if (self->epfd < 0)
1632 return pyepoll_err_closed();
1633
1634 Py_INCREF(self);
1635 return (PyObject *)self;
1636}
1637
Tal Einat6dc57e22018-06-30 23:02:48 +03001638/*[clinic input]
1639select.epoll.__exit__
1640
1641 exc_type: object = None
1642 exc_value: object = None
1643 exc_tb: object = None
1644 /
1645
1646[clinic start generated code]*/
1647
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001648static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001649select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1650 PyObject *exc_value, PyObject *exc_tb)
1651/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001652{
Christian Heimesea97eba2020-11-21 20:29:26 +01001653 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
1654 return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001655}
1656
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001657static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 {"closed", (getter)pyepoll_get_closed, NULL,
1659 "True if the epoll handler is closed"},
1660 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001661};
1662
Dino Viehlandf9190542019-09-14 15:20:27 +01001663PyDoc_STRVAR(pyepoll_doc,
1664"select.epoll(sizehint=-1, flags=0)\n\
1665\n\
1666Returns an epolling object\n\
1667\n\
1668sizehint must be a positive integer or -1 for the default size. The\n\
1669sizehint is used to optimize internal data structures. It doesn't limit\n\
1670the maximum number of monitored events.");
1671
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001672#endif /* HAVE_EPOLL */
1673
1674#ifdef HAVE_KQUEUE
1675/* **************************************************************************
1676 * kqueue interface for BSD
1677 *
1678 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1679 * All rights reserved.
1680 *
1681 * Redistribution and use in source and binary forms, with or without
1682 * modification, are permitted provided that the following conditions
1683 * are met:
1684 * 1. Redistributions of source code must retain the above copyright
1685 * notice, this list of conditions and the following disclaimer.
1686 * 2. Redistributions in binary form must reproduce the above copyright
1687 * notice, this list of conditions and the following disclaimer in the
1688 * documentation and/or other materials provided with the distribution.
1689 *
1690 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1691 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1692 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1693 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1694 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1695 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1696 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1697 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1698 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1699 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1700 * SUCH DAMAGE.
1701 */
1702
1703#ifdef HAVE_SYS_EVENT_H
1704#include <sys/event.h>
1705#endif
1706
1707PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001708"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001709\n\
1710This object is the equivalent of the struct kevent for the C API.\n\
1711\n\
1712See the kqueue manpage for more detailed information about the meaning\n\
1713of the arguments.\n\
1714\n\
1715One minor note: while you might hope that udata could store a\n\
1716reference to a python object, it cannot, because it is impossible to\n\
1717keep a proper reference count of the object once it's passed into the\n\
1718kernel. Therefore, I have restricted it to only storing an integer. I\n\
1719recommend ignoring it and simply using the 'ident' field to key off\n\
1720of. You could also set up a dictionary on the python side to store a\n\
1721udata->object mapping.");
1722
1723typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 PyObject_HEAD
1725 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001726} kqueue_event_Object;
1727
Christian Heimesea97eba2020-11-21 20:29:26 +01001728#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001729
1730typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 PyObject_HEAD
1732 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001733} kqueue_queue_Object;
1734
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001735#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1736# error uintptr_t does not match void *!
1737#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1738# define T_UINTPTRT T_ULONGLONG
1739# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001740# define UINTPTRT_FMT_UNIT "K"
1741# define INTPTRT_FMT_UNIT "L"
1742#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1743# define T_UINTPTRT T_ULONG
1744# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001745# define UINTPTRT_FMT_UNIT "k"
1746# define INTPTRT_FMT_UNIT "l"
1747#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1748# define T_UINTPTRT T_UINT
1749# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001750# define UINTPTRT_FMT_UNIT "I"
1751# define INTPTRT_FMT_UNIT "i"
1752#else
1753# error uintptr_t does not match int, long, or long long!
1754#endif
1755
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001756#if SIZEOF_LONG_LONG == 8
1757# define T_INT64 T_LONGLONG
1758# define INT64_FMT_UNIT "L"
1759#elif SIZEOF_LONG == 8
1760# define T_INT64 T_LONG
1761# define INT64_FMT_UNIT "l"
1762#elif SIZEOF_INT == 8
1763# define T_INT64 T_INT
1764# define INT64_FMT_UNIT "i"
1765#else
1766# define INT64_FMT_UNIT "_"
1767#endif
1768
1769#if SIZEOF_LONG_LONG == 4
1770# define T_UINT32 T_ULONGLONG
1771# define UINT32_FMT_UNIT "K"
1772#elif SIZEOF_LONG == 4
1773# define T_UINT32 T_ULONG
1774# define UINT32_FMT_UNIT "k"
1775#elif SIZEOF_INT == 4
1776# define T_UINT32 T_UINT
1777# define UINT32_FMT_UNIT "I"
1778#else
1779# define UINT32_FMT_UNIT "_"
1780#endif
1781
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001782/*
1783 * kevent is not standard and its members vary across BSDs.
1784 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001785#ifdef __NetBSD__
1786# define FILTER_TYPE T_UINT32
1787# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1788# define FLAGS_TYPE T_UINT32
1789# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1790# define FFLAGS_TYPE T_UINT32
1791# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001792#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001793# define FILTER_TYPE T_SHORT
1794# define FILTER_FMT_UNIT "h"
1795# define FLAGS_TYPE T_USHORT
1796# define FLAGS_FMT_UNIT "H"
1797# define FFLAGS_TYPE T_UINT
1798# define FFLAGS_FMT_UNIT "I"
1799#endif
1800
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001801#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001802# define DATA_TYPE T_INT64
1803# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001804#else
1805# define DATA_TYPE T_INTPTRT
1806# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001807#endif
1808
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001809/* Unfortunately, we can't store python objects in udata, because
1810 * kevents in the kernel can be removed without warning, which would
1811 * forever lose the refcount on the object stored with it.
1812 */
1813
1814#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1815static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001816 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1817 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1818 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001820 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1822 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001823};
1824#undef KQ_OFF
1825
1826static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001827
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001828kqueue_event_repr(kqueue_event_Object *s)
1829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 char buf[1024];
1831 PyOS_snprintf(
1832 buf, sizeof(buf),
1833 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001834 "data=0x%llx udata=%p>",
1835 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1836 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001838}
1839
1840static int
1841kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1842{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 PyObject *pfd;
1844 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1845 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001846 static const char fmt[] = "O|"
1847 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1848 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1853 &pfd, &(self->e.filter), &(self->e.flags),
1854 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1855 return -1;
1856 }
1857
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001858 if (PyLong_Check(pfd)) {
1859 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 }
1861 else {
1862 self->e.ident = PyObject_AsFileDescriptor(pfd);
1863 }
1864 if (PyErr_Occurred()) {
1865 return -1;
1866 }
1867 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868}
1869
1870static PyObject *
1871kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001874 int result;
Christian Heimesea97eba2020-11-21 20:29:26 +01001875 _selectstate *state = _selectstate_by_type(Py_TYPE(s));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876
Christian Heimesea97eba2020-11-21 20:29:26 +01001877 if (!kqueue_event_Check(o, state)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001878 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001880
1881#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1882 result = CMP(s->e.ident, o->e.ident)
1883 : CMP(s->e.filter, o->e.filter)
1884 : CMP(s->e.flags, o->e.flags)
1885 : CMP(s->e.fflags, o->e.fflags)
1886 : CMP(s->e.data, o->e.data)
1887 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1888 : 0;
1889#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001890
stratakise8b19652017-11-02 11:32:54 +01001891 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001892}
1893
Dino Viehlandf9190542019-09-14 15:20:27 +01001894static PyType_Slot kqueue_event_Type_slots[] = {
1895 {Py_tp_doc, (void*)kqueue_event_doc},
1896 {Py_tp_init, kqueue_event_init},
1897 {Py_tp_members, kqueue_event_members},
1898 {Py_tp_new, PyType_GenericNew},
1899 {Py_tp_repr, kqueue_event_repr},
1900 {Py_tp_richcompare, kqueue_event_richcompare},
1901 {0, 0},
1902};
1903
1904static PyType_Spec kqueue_event_Type_spec = {
1905 "select.kevent",
1906 sizeof(kqueue_event_Object),
1907 0,
1908 Py_TPFLAGS_DEFAULT,
1909 kqueue_event_Type_slots
1910};
1911
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001912static PyObject *
1913kqueue_queue_err_closed(void)
1914{
Victor Stinner13423c32013-08-22 00:19:50 +02001915 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001917}
1918
1919static int
1920kqueue_queue_internal_close(kqueue_queue_Object *self)
1921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 int save_errno = 0;
1923 if (self->kqfd >= 0) {
1924 int kqfd = self->kqfd;
1925 self->kqfd = -1;
1926 Py_BEGIN_ALLOW_THREADS
1927 if (close(kqfd) < 0)
1928 save_errno = errno;
1929 Py_END_ALLOW_THREADS
1930 }
1931 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001932}
1933
1934static PyObject *
1935newKqueue_Object(PyTypeObject *type, SOCKET fd)
1936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001938 assert(type != NULL);
1939 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1940 assert(queue_alloc != NULL);
1941 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 if (self == NULL) {
1943 return NULL;
1944 }
1945
1946 if (fd == -1) {
1947 Py_BEGIN_ALLOW_THREADS
1948 self->kqfd = kqueue();
1949 Py_END_ALLOW_THREADS
1950 }
1951 else {
1952 self->kqfd = fd;
1953 }
1954 if (self->kqfd < 0) {
1955 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001956 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 return NULL;
1958 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001959
1960 if (fd == -1) {
1961 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1962 Py_DECREF(self);
1963 return NULL;
1964 }
1965 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001967}
1968
Tal Einat6dc57e22018-06-30 23:02:48 +03001969/*[clinic input]
1970@classmethod
1971select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001972
Tal Einat6dc57e22018-06-30 23:02:48 +03001973Kqueue syscall wrapper.
1974
1975For example, to start watching a socket for input:
1976>>> kq = kqueue()
1977>>> sock = socket()
1978>>> sock.connect((host, port))
1979>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1980
1981To wait one second for it to become writeable:
1982>>> kq.control(None, 1, 1000)
1983
1984To stop listening:
1985>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
1986[clinic start generated code]*/
1987
1988static PyObject *
1989select_kqueue_impl(PyTypeObject *type)
1990/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
1991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001993}
1994
1995static void
1996kqueue_queue_dealloc(kqueue_queue_Object *self)
1997{
Dino Viehlandf9190542019-09-14 15:20:27 +01001998 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002000 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2001 kqueue_free((PyObject *)self);
2002 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003}
2004
Tal Einat6dc57e22018-06-30 23:02:48 +03002005/*[clinic input]
2006select.kqueue.close
2007
2008Close the kqueue control file descriptor.
2009
2010Further operations on the kqueue object will raise an exception.
2011[clinic start generated code]*/
2012
2013static PyObject *
2014select_kqueue_close_impl(kqueue_queue_Object *self)
2015/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 errno = kqueue_queue_internal_close(self);
2018 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002019 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 return NULL;
2021 }
2022 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002023}
2024
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002025static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002026kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 if (self->kqfd < 0)
2029 Py_RETURN_TRUE;
2030 else
2031 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002032}
2033
Tal Einat6dc57e22018-06-30 23:02:48 +03002034/*[clinic input]
2035select.kqueue.fileno
2036
2037Return the kqueue control file descriptor.
2038[clinic start generated code]*/
2039
2040static PyObject *
2041select_kqueue_fileno_impl(kqueue_queue_Object *self)
2042/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002043{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 if (self->kqfd < 0)
2045 return kqueue_queue_err_closed();
2046 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002047}
2048
Tal Einat6dc57e22018-06-30 23:02:48 +03002049/*[clinic input]
2050@classmethod
2051select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002052
Tal Einat6dc57e22018-06-30 23:02:48 +03002053 fd: int
2054 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002055
Tal Einat6dc57e22018-06-30 23:02:48 +03002056Create a kqueue object from a given control fd.
2057[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002058
2059static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002060select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2061/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002062{
Tal Einat6dc57e22018-06-30 23:02:48 +03002063 SOCKET s_fd = (SOCKET)fd;
2064
2065 return newKqueue_Object(type, s_fd);
2066}
2067
2068/*[clinic input]
2069select.kqueue.control
2070
2071 changelist: object
2072 Must be an iterable of kevent objects describing the changes to be made
2073 to the kernel's watch list or None.
2074 maxevents: int
2075 The maximum number of events that the kernel will return.
2076 timeout as otimeout: object = None
2077 The maximum time to wait in seconds, or else None to wait forever.
2078 This accepts floats for smaller timeouts, too.
2079 /
2080
2081Calls the kernel kevent function.
2082[clinic start generated code]*/
2083
2084static PyObject *
2085select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2086 int maxevents, PyObject *otimeout)
2087/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 int gotevents = 0;
2090 int nchanges = 0;
2091 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002092 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 PyObject *result = NULL;
2094 struct kevent *evl = NULL;
2095 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002096 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002098 _PyTime_t timeout, deadline = 0;
Christian Heimesea97eba2020-11-21 20:29:26 +01002099 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 if (self->kqfd < 0)
2102 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002103
Tal Einat6dc57e22018-06-30 23:02:48 +03002104 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 PyErr_Format(PyExc_ValueError,
2106 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002107 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 return NULL;
2109 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002110
Tal Einat6dc57e22018-06-30 23:02:48 +03002111 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 ptimeoutspec = NULL;
2113 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002114 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002115 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002116 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002117 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002118 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002119 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002120 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002121 return NULL;
2122 }
2123
Victor Stinner4448c082015-03-31 11:48:34 +02002124 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002125 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Victor Stinner4448c082015-03-31 11:48:34 +02002127 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 PyErr_SetString(PyExc_ValueError,
2129 "timeout must be positive or None");
2130 return NULL;
2131 }
Victor Stinner4448c082015-03-31 11:48:34 +02002132 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002134
Tal Einat6dc57e22018-06-30 23:02:48 +03002135 if (changelist != Py_None) {
2136 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002137 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 return NULL;
2139 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002140 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2141 PyErr_SetString(PyExc_OverflowError,
2142 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 goto error;
2144 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002145 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 chl = PyMem_New(struct kevent, nchanges);
2148 if (chl == NULL) {
2149 PyErr_NoMemory();
2150 goto error;
2151 }
Christian Heimesea97eba2020-11-21 20:29:26 +01002152 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Serhiy Storchakade072102017-10-12 22:17:46 +03002153 for (i = 0; i < nchanges; ++i) {
2154 ei = PySequence_Fast_GET_ITEM(seq, i);
Christian Heimesea97eba2020-11-21 20:29:26 +01002155 if (!kqueue_event_Check(ei, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 PyErr_SetString(PyExc_TypeError,
2157 "changelist must be an iterable of "
2158 "select.kevent objects");
2159 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002161 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002163 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002167 if (maxevents) {
2168 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 if (evl == NULL) {
2170 PyErr_NoMemory();
2171 goto error;
2172 }
2173 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002174
Victor Stinner4448c082015-03-31 11:48:34 +02002175 if (ptimeoutspec)
2176 deadline = _PyTime_GetMonotonicClock() + timeout;
2177
2178 do {
2179 Py_BEGIN_ALLOW_THREADS
2180 errno = 0;
2181 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002182 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002183 Py_END_ALLOW_THREADS
2184
2185 if (errno != EINTR)
2186 break;
2187
2188 /* kevent() was interrupted by a signal */
2189 if (PyErr_CheckSignals())
2190 goto error;
2191
2192 if (ptimeoutspec) {
2193 timeout = deadline - _PyTime_GetMonotonicClock();
2194 if (timeout < 0) {
2195 gotevents = 0;
2196 break;
2197 }
2198 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2199 goto error;
2200 /* retry kevent() with the recomputed timeout */
2201 }
2202 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 if (gotevents == -1) {
2205 PyErr_SetFromErrno(PyExc_OSError);
2206 goto error;
2207 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 result = PyList_New(gotevents);
2210 if (result == NULL) {
2211 goto error;
2212 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002214 for (i = 0; i < gotevents; i++) {
2215 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002216
Christian Heimesea97eba2020-11-21 20:29:26 +01002217 ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 if (ch == NULL) {
2219 goto error;
2220 }
2221 ch->e = evl[i];
2222 PyList_SET_ITEM(result, i, (PyObject *)ch);
2223 }
2224 PyMem_Free(chl);
2225 PyMem_Free(evl);
2226 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002227
2228 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 PyMem_Free(chl);
2230 PyMem_Free(evl);
2231 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002232 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002234}
2235
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002236static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 {"closed", (getter)kqueue_queue_get_closed, NULL,
2238 "True if the kqueue handler is closed"},
2239 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002240};
2241
Tal Einat6dc57e22018-06-30 23:02:48 +03002242#endif /* HAVE_KQUEUE */
2243
2244
2245/* ************************************************************************ */
2246
2247#include "clinic/selectmodule.c.h"
2248
2249#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2250
2251static PyMethodDef poll_methods[] = {
2252 SELECT_POLL_REGISTER_METHODDEF
2253 SELECT_POLL_MODIFY_METHODDEF
2254 SELECT_POLL_UNREGISTER_METHODDEF
2255 SELECT_POLL_POLL_METHODDEF
2256 {NULL, NULL} /* sentinel */
2257};
2258
Dino Viehlandf9190542019-09-14 15:20:27 +01002259
2260static PyType_Slot poll_Type_slots[] = {
2261 {Py_tp_dealloc, poll_dealloc},
2262 {Py_tp_methods, poll_methods},
Dino Viehlandf9190542019-09-14 15:20:27 +01002263 {0, 0},
2264};
2265
2266static PyType_Spec poll_Type_spec = {
Erlend Egeberg Aasland387397f2021-04-30 15:49:17 +02002267 .name = "select.poll",
2268 .basicsize = sizeof(pollObject),
2269 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
2270 .slots = poll_Type_slots,
Tal Einat6dc57e22018-06-30 23:02:48 +03002271};
2272
2273#ifdef HAVE_SYS_DEVPOLL_H
2274
2275static PyMethodDef devpoll_methods[] = {
2276 SELECT_DEVPOLL_REGISTER_METHODDEF
2277 SELECT_DEVPOLL_MODIFY_METHODDEF
2278 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2279 SELECT_DEVPOLL_POLL_METHODDEF
2280 SELECT_DEVPOLL_CLOSE_METHODDEF
2281 SELECT_DEVPOLL_FILENO_METHODDEF
2282 {NULL, NULL} /* sentinel */
2283};
2284
Tal Einat6dc57e22018-06-30 23:02:48 +03002285#endif /* HAVE_SYS_DEVPOLL_H */
2286
2287#endif /* HAVE_POLL */
2288
2289#ifdef HAVE_EPOLL
2290
2291static PyMethodDef pyepoll_methods[] = {
2292 SELECT_EPOLL_FROMFD_METHODDEF
2293 SELECT_EPOLL_CLOSE_METHODDEF
2294 SELECT_EPOLL_FILENO_METHODDEF
2295 SELECT_EPOLL_MODIFY_METHODDEF
2296 SELECT_EPOLL_REGISTER_METHODDEF
2297 SELECT_EPOLL_UNREGISTER_METHODDEF
2298 SELECT_EPOLL_POLL_METHODDEF
2299 SELECT_EPOLL___ENTER___METHODDEF
2300 SELECT_EPOLL___EXIT___METHODDEF
2301 {NULL, NULL},
2302};
2303
Dino Viehlandf9190542019-09-14 15:20:27 +01002304static PyType_Slot pyEpoll_Type_slots[] = {
2305 {Py_tp_dealloc, pyepoll_dealloc},
2306 {Py_tp_doc, (void*)pyepoll_doc},
2307 {Py_tp_getattro, PyObject_GenericGetAttr},
2308 {Py_tp_getset, pyepoll_getsetlist},
2309 {Py_tp_methods, pyepoll_methods},
2310 {Py_tp_new, select_epoll},
2311 {0, 0},
2312};
2313
2314static PyType_Spec pyEpoll_Type_spec = {
2315 "select.epoll",
2316 sizeof(pyEpoll_Object),
2317 0,
2318 Py_TPFLAGS_DEFAULT,
2319 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002320};
2321
2322#endif /* HAVE_EPOLL */
2323
2324#ifdef HAVE_KQUEUE
2325
Tal Einat6dc57e22018-06-30 23:02:48 +03002326static PyMethodDef kqueue_queue_methods[] = {
2327 SELECT_KQUEUE_FROMFD_METHODDEF
2328 SELECT_KQUEUE_CLOSE_METHODDEF
2329 SELECT_KQUEUE_FILENO_METHODDEF
2330 SELECT_KQUEUE_CONTROL_METHODDEF
2331 {NULL, NULL},
2332};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002333
Dino Viehlandf9190542019-09-14 15:20:27 +01002334static PyType_Slot kqueue_queue_Type_slots[] = {
2335 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002336 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002337 {Py_tp_getset, kqueue_queue_getsetlist},
2338 {Py_tp_methods, kqueue_queue_methods},
2339 {Py_tp_new, select_kqueue},
2340 {0, 0},
2341};
2342
2343static PyType_Spec kqueue_queue_Type_spec = {
2344 "select.kqueue",
2345 sizeof(kqueue_queue_Object),
2346 0,
2347 Py_TPFLAGS_DEFAULT,
2348 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002349};
2350
2351#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002352
2353
2354
2355
2356
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002357/* ************************************************************************ */
2358
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002359
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002360static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002361 SELECT_SELECT_METHODDEF
2362 SELECT_POLL_METHODDEF
2363 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002365};
2366
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002367PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002368"This module supports asynchronous I/O on multiple file descriptors.\n\
2369\n\
2370*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002371On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002372
Martin v. Löwis1a214512008-06-11 05:26:20 +00002373
Dino Viehlandf9190542019-09-14 15:20:27 +01002374
2375static int
2376_select_traverse(PyObject *module, visitproc visit, void *arg)
2377{
Christian Heimesea97eba2020-11-21 20:29:26 +01002378 _selectstate *state = get_select_state(module);
2379
2380 Py_VISIT(state->close);
2381 Py_VISIT(state->poll_Type);
2382 Py_VISIT(state->devpoll_Type);
2383 Py_VISIT(state->pyEpoll_Type);
2384 Py_VISIT(state->kqueue_event_Type);
2385 Py_VISIT(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002386 return 0;
2387}
2388
2389static int
2390_select_clear(PyObject *module)
2391{
Christian Heimesea97eba2020-11-21 20:29:26 +01002392 _selectstate *state = get_select_state(module);
2393
2394 Py_CLEAR(state->close);
2395 Py_CLEAR(state->poll_Type);
2396 Py_CLEAR(state->devpoll_Type);
2397 Py_CLEAR(state->pyEpoll_Type);
2398 Py_CLEAR(state->kqueue_event_Type);
2399 Py_CLEAR(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002400 return 0;
2401}
2402
2403static void
2404_select_free(void *module)
2405{
2406 _select_clear((PyObject *)module);
2407}
2408
Christian Heimesea97eba2020-11-21 20:29:26 +01002409int
2410_select_exec(PyObject *m)
Guido van Rossumed233a51992-06-23 09:07:03 +00002411{
Christian Heimesea97eba2020-11-21 20:29:26 +01002412 _selectstate *state = get_select_state(m);
Fred Drake4baedc12002-04-01 14:53:37 +00002413
Christian Heimesea97eba2020-11-21 20:29:26 +01002414 state->close = PyUnicode_InternFromString("close");
2415 if (state->close == NULL) {
2416 return -1;
2417 }
2418 if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
2419 return -1;
2420 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002421
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002422#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002423#ifdef HAVE_BROKEN_PIPE_BUF
2424#undef PIPE_BUF
2425#define PIPE_BUF 512
2426#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002427 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002428#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002429
Charles-François Natali986a56c2013-01-19 12:19:10 +01002430#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002431#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 if (select_have_broken_poll()) {
2433 if (PyObject_DelAttrString(m, "poll") == -1) {
2434 PyErr_Clear();
2435 }
2436 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002437#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002439#endif
Christian Heimesea97eba2020-11-21 20:29:26 +01002440 state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2441 m, &poll_Type_spec, NULL);
2442 if (state->poll_Type == NULL) {
2443 return -1;
2444 }
Dino Viehlandf9190542019-09-14 15:20:27 +01002445
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002446 PyModule_AddIntMacro(m, POLLIN);
2447 PyModule_AddIntMacro(m, POLLPRI);
2448 PyModule_AddIntMacro(m, POLLOUT);
2449 PyModule_AddIntMacro(m, POLLERR);
2450 PyModule_AddIntMacro(m, POLLHUP);
2451 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002452
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002453#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002454 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002455#endif
2456#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002457 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002458#endif
2459#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002460 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002461#endif
2462#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002463 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002464#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002465#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002466 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002467#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002468#ifdef POLLRDHUP
2469 /* Kernel 2.6.17+ */
2470 PyModule_AddIntMacro(m, POLLRDHUP);
2471#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002473#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002474
Jesus Cead8b9ae62011-11-14 19:07:41 +01002475#ifdef HAVE_SYS_DEVPOLL_H
Christian Heimesea97eba2020-11-21 20:29:26 +01002476 state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2477 m, &devpoll_Type_spec, NULL);
2478 if (state->devpoll_Type == NULL) {
2479 return -1;
2480 }
Jesus Cead8b9ae62011-11-14 19:07:41 +01002481#endif
2482
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002483#ifdef HAVE_EPOLL
Christian Heimesea97eba2020-11-21 20:29:26 +01002484 state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2485 m, &pyEpoll_Type_spec, NULL);
2486 if (state->pyEpoll_Type == NULL) {
2487 return -1;
2488 }
2489 if (PyModule_AddType(m, state->pyEpoll_Type) < 0) {
2490 return -1;
2491 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002492
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002493 PyModule_AddIntMacro(m, EPOLLIN);
2494 PyModule_AddIntMacro(m, EPOLLOUT);
2495 PyModule_AddIntMacro(m, EPOLLPRI);
2496 PyModule_AddIntMacro(m, EPOLLERR);
2497 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002498#ifdef EPOLLRDHUP
2499 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002500 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002501#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002502 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002503#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002505 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002506#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002507#ifdef EPOLLEXCLUSIVE
2508 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2509#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002510
2511#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002512 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002513#endif
2514#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002515 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002516#endif
2517#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002518 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002519#endif
2520#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002521 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002522#endif
2523#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002524 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002525#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002526
Benjamin Peterson95c16622011-12-27 15:36:32 -06002527#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002528 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002529#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002530#endif /* HAVE_EPOLL */
2531
2532#ifdef HAVE_KQUEUE
Christian Heimesea97eba2020-11-21 20:29:26 +01002533 state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2534 m, &kqueue_event_Type_spec, NULL);
2535 if (state->kqueue_event_Type == NULL) {
2536 return -1;
2537 }
2538 if (PyModule_AddType(m, state->kqueue_event_Type) < 0) {
2539 return -1;
2540 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002541
Christian Heimesea97eba2020-11-21 20:29:26 +01002542 state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2543 m, &kqueue_queue_Type_spec, NULL);
2544 if (state->kqueue_queue_Type == NULL) {
2545 return -1;
2546 }
2547 if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) {
2548 return -1;
2549 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550
2551 /* event filters */
2552 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2553 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002554#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002556#endif
2557#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002559#endif
2560#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002562#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002563#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002565#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002566#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002567 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002568#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 /* event flags */
2572 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2573 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2574 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2575 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2576 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2577 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002578
Berker Peksag7ec64562016-09-14 18:16:59 +03002579#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002580 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002581#endif
2582#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002584#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2587 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002590#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002592#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002595#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002596 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2597 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2598 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2599 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2600 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2601 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2602 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002603#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002606#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2608 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2609 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2610 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2611 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2615 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002616#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617
2618 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002619#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2621 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2622 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002623#endif
2624
2625#endif /* HAVE_KQUEUE */
Christian Heimesea97eba2020-11-21 20:29:26 +01002626 return 0;
2627}
2628
2629static PyModuleDef_Slot _select_slots[] = {
2630 {Py_mod_exec, _select_exec},
2631 {0, NULL}
2632};
2633
2634static struct PyModuleDef selectmodule = {
2635 PyModuleDef_HEAD_INIT,
2636 .m_name = "select",
2637 .m_doc = module_doc,
2638 .m_size = sizeof(_selectstate),
2639 .m_methods = select_methods,
2640 .m_slots = _select_slots,
2641 .m_traverse = _select_traverse,
2642 .m_clear = _select_clear,
2643 .m_free = _select_free,
2644};
2645
2646PyMODINIT_FUNC
2647PyInit_select(void)
2648{
2649 return PyModuleDef_Init(&selectmodule);
Guido van Rossumed233a51992-06-23 09:07:03 +00002650}