blob: f80da5895401feb4bebce8501e1425c003a7674f [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
Dino Viehlandf9190542019-09-14 15:20:27 +0100731static PyObject *
732poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
733{
734 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
735 return NULL;
736}
737
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000738static void
739poll_dealloc(pollObject *self)
740{
Dino Viehlandf9190542019-09-14 15:20:27 +0100741 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 if (self->ufds != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100743 PyMem_Free(self->ufds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 Py_XDECREF(self->dict);
Victor Stinner32bd68c2020-12-01 10:37:39 +0100745 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100746 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000747}
748
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000749
Jesus Cead8b9ae62011-11-14 19:07:41 +0100750#ifdef HAVE_SYS_DEVPOLL_H
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300751static PyMethodDef devpoll_methods[];
752
Jesus Cead8b9ae62011-11-14 19:07:41 +0100753typedef struct {
754 PyObject_HEAD
755 int fd_devpoll;
756 int max_n_fds;
757 int n_fds;
758 struct pollfd *fds;
759} devpollObject;
760
Victor Stinner13423c32013-08-22 00:19:50 +0200761static PyObject *
762devpoll_err_closed(void)
763{
764 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
765 return NULL;
766}
767
Jesus Cead8b9ae62011-11-14 19:07:41 +0100768static int devpoll_flush(devpollObject *self)
769{
770 int size, n;
771
772 if (!self->n_fds) return 0;
773
774 size = sizeof(struct pollfd)*self->n_fds;
775 self->n_fds = 0;
776
Victor Stinner54799672015-03-19 23:33:09 +0100777 n = _Py_write(self->fd_devpoll, self->fds, size);
778 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100779 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100780
Jesus Cead8b9ae62011-11-14 19:07:41 +0100781 if (n < size) {
782 /*
783 ** Data writed to /dev/poll is a binary data structure. It is not
784 ** clear what to do if a partial write occurred. For now, raise
785 ** an exception and see if we actually found this problem in
786 ** the wild.
787 ** See http://bugs.python.org/issue6397.
788 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300789 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100790 "Please, report at http://bugs.python.org/. "
791 "Data to report: Size tried: %d, actual size written: %d.",
792 size, n);
793 return -1;
794 }
795 return 0;
796}
797
798static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300799internal_devpoll_register(devpollObject *self, int fd,
800 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100801{
Victor Stinner13423c32013-08-22 00:19:50 +0200802 if (self->fd_devpoll < 0)
803 return devpoll_err_closed();
804
Jesus Cead8b9ae62011-11-14 19:07:41 +0100805 if (remove) {
806 self->fds[self->n_fds].fd = fd;
807 self->fds[self->n_fds].events = POLLREMOVE;
808
809 if (++self->n_fds == self->max_n_fds) {
810 if (devpoll_flush(self))
811 return NULL;
812 }
813 }
814
815 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200816 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100817
818 if (++self->n_fds == self->max_n_fds) {
819 if (devpoll_flush(self))
820 return NULL;
821 }
822
823 Py_RETURN_NONE;
824}
825
Tal Einat6dc57e22018-06-30 23:02:48 +0300826/*[clinic input]
827select.devpoll.register
828
829 fd: fildes
830 either an integer, or an object with a fileno() method returning
831 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700832 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300833 an optional bitmask describing the type of events to check for
834 /
835
836Register a file descriptor with the polling object.
837[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100838
839static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300840select_devpoll_register_impl(devpollObject *self, int fd,
841 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700842/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100843{
Tal Einat6dc57e22018-06-30 23:02:48 +0300844 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100845}
846
Tal Einat6dc57e22018-06-30 23:02:48 +0300847/*[clinic input]
848select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100849
Tal Einat6dc57e22018-06-30 23:02:48 +0300850 fd: fildes
851 either an integer, or an object with a fileno() method returning
852 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700853 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300854 an optional bitmask describing the type of events to check for
855 /
856
857Modify a possible already registered file descriptor.
858[clinic start generated code]*/
859
860static PyObject *
861select_devpoll_modify_impl(devpollObject *self, int fd,
862 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700863/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100864{
Tal Einat6dc57e22018-06-30 23:02:48 +0300865 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100866}
867
Tal Einat6dc57e22018-06-30 23:02:48 +0300868/*[clinic input]
869select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100870
Tal Einat6dc57e22018-06-30 23:02:48 +0300871 fd: fildes
872 /
873
874Remove a file descriptor being tracked by the polling object.
875[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100876
877static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300878select_devpoll_unregister_impl(devpollObject *self, int fd)
879/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100880{
Victor Stinner13423c32013-08-22 00:19:50 +0200881 if (self->fd_devpoll < 0)
882 return devpoll_err_closed();
883
Jesus Cead8b9ae62011-11-14 19:07:41 +0100884 self->fds[self->n_fds].fd = fd;
885 self->fds[self->n_fds].events = POLLREMOVE;
886
887 if (++self->n_fds == self->max_n_fds) {
888 if (devpoll_flush(self))
889 return NULL;
890 }
891
892 Py_RETURN_NONE;
893}
894
Tal Einat6dc57e22018-06-30 23:02:48 +0300895/*[clinic input]
896select.devpoll.poll
897 timeout as timeout_obj: object = None
898 /
899
900Polls the set of registered file descriptors.
901
902Returns a list containing any descriptors that have events or errors to
903report, as a list of (fd, event) 2-tuples.
904[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100905
906static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300907select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
908/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909{
910 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200911 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100913 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200914 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100915
Victor Stinner13423c32013-08-22 00:19:50 +0200916 if (self->fd_devpoll < 0)
917 return devpoll_err_closed();
918
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300920 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100921 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200922 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100923 }
924 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200925 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100926 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200927 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
928 PyErr_SetString(PyExc_TypeError,
929 "timeout must be an integer or None");
930 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100931 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100933
Pablo Galindo2c15b292017-10-17 15:14:41 +0100934 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200935 if (ms < -1 || ms > INT_MAX) {
936 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
937 return NULL;
938 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100939 }
940
941 if (devpoll_flush(self))
942 return NULL;
943
944 dvp.dp_fds = self->fds;
945 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200946 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100947
Victor Stinner45ca48b2015-03-31 12:10:33 +0200948 if (timeout >= 0)
949 deadline = _PyTime_GetMonotonicClock() + timeout;
950
951 do {
952 /* call devpoll() */
953 Py_BEGIN_ALLOW_THREADS
954 errno = 0;
955 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
956 Py_END_ALLOW_THREADS
957
958 if (errno != EINTR)
959 break;
960
961 /* devpoll() was interrupted by a signal */
962 if (PyErr_CheckSignals())
963 return NULL;
964
965 if (timeout >= 0) {
966 timeout = deadline - _PyTime_GetMonotonicClock();
967 if (timeout < 0) {
968 poll_result = 0;
969 break;
970 }
971 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
972 dvp.dp_timeout = (int)ms;
973 /* retry devpoll() with the recomputed timeout */
974 }
975 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976
977 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300978 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100979 return NULL;
980 }
981
982 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100983 result_list = PyList_New(poll_result);
984 if (!result_list)
985 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200986
987 for (i = 0; i < poll_result; i++) {
988 num1 = PyLong_FromLong(self->fds[i].fd);
989 num2 = PyLong_FromLong(self->fds[i].revents);
990 if ((num1 == NULL) || (num2 == NULL)) {
991 Py_XDECREF(num1);
992 Py_XDECREF(num2);
993 goto error;
994 }
995 value = PyTuple_Pack(2, num1, num2);
996 Py_DECREF(num1);
997 Py_DECREF(num2);
998 if (value == NULL)
999 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001000 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001001 }
1002
1003 return result_list;
1004
1005 error:
1006 Py_DECREF(result_list);
1007 return NULL;
1008}
1009
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001010static int
1011devpoll_internal_close(devpollObject *self)
1012{
1013 int save_errno = 0;
1014 if (self->fd_devpoll >= 0) {
1015 int fd = self->fd_devpoll;
1016 self->fd_devpoll = -1;
1017 Py_BEGIN_ALLOW_THREADS
1018 if (close(fd) < 0)
1019 save_errno = errno;
1020 Py_END_ALLOW_THREADS
1021 }
1022 return save_errno;
1023}
1024
Tal Einat6dc57e22018-06-30 23:02:48 +03001025/*[clinic input]
1026select.devpoll.close
1027
1028Close the devpoll file descriptor.
1029
1030Further operations on the devpoll object will raise an exception.
1031[clinic start generated code]*/
1032
1033static PyObject *
1034select_devpoll_close_impl(devpollObject *self)
1035/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001036{
1037 errno = devpoll_internal_close(self);
1038 if (errno < 0) {
1039 PyErr_SetFromErrno(PyExc_OSError);
1040 return NULL;
1041 }
1042 Py_RETURN_NONE;
1043}
1044
Victor Stinner13423c32013-08-22 00:19:50 +02001045static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001046devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001047{
1048 if (self->fd_devpoll < 0)
1049 Py_RETURN_TRUE;
1050 else
1051 Py_RETURN_FALSE;
1052}
1053
Tal Einat6dc57e22018-06-30 23:02:48 +03001054/*[clinic input]
1055select.devpoll.fileno
1056
1057Return the file descriptor.
1058[clinic start generated code]*/
1059
1060static PyObject *
1061select_devpoll_fileno_impl(devpollObject *self)
1062/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001063{
1064 if (self->fd_devpoll < 0)
1065 return devpoll_err_closed();
1066 return PyLong_FromLong(self->fd_devpoll);
1067}
1068
Victor Stinner13423c32013-08-22 00:19:50 +02001069static PyGetSetDef devpoll_getsetlist[] = {
1070 {"closed", (getter)devpoll_get_closed, NULL,
1071 "True if the devpoll object is closed"},
1072 {0},
1073};
1074
Jesus Cead8b9ae62011-11-14 19:07:41 +01001075static devpollObject *
Christian Heimesea97eba2020-11-21 20:29:26 +01001076newDevPollObject(PyObject *module)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001077{
1078 devpollObject *self;
1079 int fd_devpoll, limit_result;
1080 struct pollfd *fds;
1081 struct rlimit limit;
1082
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083 /*
1084 ** If we try to process more that getrlimit()
1085 ** fds, the kernel will give an error, so
1086 ** we set the limit here. It is a dynamic
1087 ** value, because we can change rlimit() anytime.
1088 */
1089 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090 if (limit_result == -1) {
1091 PyErr_SetFromErrno(PyExc_OSError);
1092 return NULL;
1093 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001094
1095 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1096 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001097 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001098
1099 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1100 if (fds == NULL) {
1101 close(fd_devpoll);
1102 PyErr_NoMemory();
1103 return NULL;
1104 }
1105
Christian Heimesea97eba2020-11-21 20:29:26 +01001106 self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001107 if (self == NULL) {
1108 close(fd_devpoll);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001109 PyMem_Free(fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001110 return NULL;
1111 }
1112 self->fd_devpoll = fd_devpoll;
1113 self->max_n_fds = limit.rlim_cur;
1114 self->n_fds = 0;
1115 self->fds = fds;
1116
1117 return self;
1118}
1119
Dino Viehlandf9190542019-09-14 15:20:27 +01001120static PyObject *
1121devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1122{
1123 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1124 return NULL;
1125}
1126
Jesus Cead8b9ae62011-11-14 19:07:41 +01001127static void
1128devpoll_dealloc(devpollObject *self)
1129{
Dino Viehlandf9190542019-09-14 15:20:27 +01001130 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001131 (void)devpoll_internal_close(self);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001132 PyMem_Free(self->fds);
Victor Stinner32bd68c2020-12-01 10:37:39 +01001133 PyObject_Free(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001134 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001135}
1136
Dino Viehlandf9190542019-09-14 15:20:27 +01001137static PyType_Slot devpoll_Type_slots[] = {
1138 {Py_tp_dealloc, devpoll_dealloc},
1139 {Py_tp_getset, devpoll_getsetlist},
1140 {Py_tp_methods, devpoll_methods},
1141 {Py_tp_new, devpoll_new},
1142 {0, 0},
1143};
1144
1145static PyType_Spec devpoll_Type_spec = {
1146 "select.devpoll",
1147 sizeof(devpollObject),
1148 0,
1149 Py_TPFLAGS_DEFAULT,
1150 devpoll_Type_slots
1151};
1152
Jesus Cead8b9ae62011-11-14 19:07:41 +01001153#endif /* HAVE_SYS_DEVPOLL_H */
1154
1155
Tal Einat6dc57e22018-06-30 23:02:48 +03001156/*[clinic input]
1157select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001158
Tal Einat6dc57e22018-06-30 23:02:48 +03001159Returns a polling object.
1160
1161This object supports registering and unregistering file descriptors, and then
1162polling them for I/O events.
1163[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001164
1165static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001166select_poll_impl(PyObject *module)
1167/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001168{
Christian Heimesea97eba2020-11-21 20:29:26 +01001169 return (PyObject *)newPollObject(module);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001170}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171
Jesus Cead8b9ae62011-11-14 19:07:41 +01001172#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001173
1174/*[clinic input]
1175select.devpoll
1176
1177Returns a polling object.
1178
1179This object supports registering and unregistering file descriptors, and then
1180polling them for I/O events.
1181[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001182
1183static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001184select_devpoll_impl(PyObject *module)
1185/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001186{
Christian Heimesea97eba2020-11-21 20:29:26 +01001187 return (PyObject *)newDevPollObject(module);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001188}
1189#endif
1190
1191
Thomas Wouters477c8d52006-05-27 19:21:47 +00001192#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194 * On some systems poll() sets errno on invalid file descriptors. We test
1195 * for this at runtime because this bug may be fixed or introduced between
1196 * OS releases.
1197 */
1198static int select_have_broken_poll(void)
1199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 int poll_test;
1201 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 /* Create a file descriptor to make invalid */
1206 if (pipe(filedes) < 0) {
1207 return 1;
1208 }
1209 poll_struct.fd = filedes[0];
1210 close(filedes[0]);
1211 close(filedes[1]);
1212 poll_test = poll(&poll_struct, 1, 0);
1213 if (poll_test < 0) {
1214 return 1;
1215 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1216 return 1;
1217 }
1218 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001219}
1220#endif /* __APPLE__ */
1221
1222#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001223
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001224#ifdef HAVE_EPOLL
1225/* **************************************************************************
1226 * epoll interface for Linux 2.6
1227 *
1228 * Written by Christian Heimes
1229 * Inspired by Twisted's _epoll.pyx and select.poll()
1230 */
1231
1232#ifdef HAVE_SYS_EPOLL_H
1233#include <sys/epoll.h>
1234#endif
1235
1236typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001238 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001239} pyEpoll_Object;
1240
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001241static PyObject *
1242pyepoll_err_closed(void)
1243{
Victor Stinner13423c32013-08-22 00:19:50 +02001244 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001246}
1247
1248static int
1249pyepoll_internal_close(pyEpoll_Object *self)
1250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 int save_errno = 0;
1252 if (self->epfd >= 0) {
1253 int epfd = self->epfd;
1254 self->epfd = -1;
1255 Py_BEGIN_ALLOW_THREADS
1256 if (close(epfd) < 0)
1257 save_errno = errno;
1258 Py_END_ALLOW_THREADS
1259 }
1260 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001261}
1262
1263static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001264newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001267 assert(type != NULL);
1268 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1269 assert(epoll_alloc != NULL);
1270 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (self == NULL)
1272 return NULL;
1273
1274 if (fd == -1) {
1275 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001276#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001277 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1278#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001279 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001280#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 Py_END_ALLOW_THREADS
1282 }
1283 else {
1284 self->epfd = fd;
1285 }
1286 if (self->epfd < 0) {
1287 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001288 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 return NULL;
1290 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001291
1292#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001293 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001294 Py_DECREF(self);
1295 return NULL;
1296 }
1297#endif
1298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001300}
1301
1302
Tal Einat6dc57e22018-06-30 23:02:48 +03001303/*[clinic input]
1304@classmethod
1305select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001306
Tal Einat6dc57e22018-06-30 23:02:48 +03001307 sizehint: int = -1
1308 The expected number of events to be registered. It must be positive,
1309 or -1 to use the default. It is only used on older systems where
1310 epoll_create1() is not available; otherwise it has no effect (though its
1311 value is still checked).
1312 flags: int = 0
1313 Deprecated and completely ignored. However, when supplied, its value
1314 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1315
1316Returns an epolling object.
1317[clinic start generated code]*/
1318
1319static PyObject *
1320select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1321/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1322{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001323 if (sizehint == -1) {
1324 sizehint = FD_SETSIZE - 1;
1325 }
1326 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001327 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001328 return NULL;
1329 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001330
1331#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001332 if (flags && flags != EPOLL_CLOEXEC) {
1333 PyErr_SetString(PyExc_OSError, "invalid flags");
1334 return NULL;
1335 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001336#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001337
Berker Peksage2197d12016-09-26 23:30:41 +03001338 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001339}
1340
1341
1342static void
1343pyepoll_dealloc(pyEpoll_Object *self)
1344{
Dino Viehlandf9190542019-09-14 15:20:27 +01001345 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001347 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1348 epoll_free((PyObject *)self);
1349 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001350}
1351
Tal Einat6dc57e22018-06-30 23:02:48 +03001352/*[clinic input]
1353select.epoll.close
1354
1355Close the epoll control file descriptor.
1356
1357Further operations on the epoll object will raise an exception.
1358[clinic start generated code]*/
1359
1360static PyObject *
1361select_epoll_close_impl(pyEpoll_Object *self)
1362/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 errno = pyepoll_internal_close(self);
1365 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001366 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 return NULL;
1368 }
1369 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370}
1371
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372
1373static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001374pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 if (self->epfd < 0)
1377 Py_RETURN_TRUE;
1378 else
1379 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380}
1381
Tal Einat6dc57e22018-06-30 23:02:48 +03001382/*[clinic input]
1383select.epoll.fileno
1384
1385Return the epoll control file descriptor.
1386[clinic start generated code]*/
1387
1388static PyObject *
1389select_epoll_fileno_impl(pyEpoll_Object *self)
1390/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 if (self->epfd < 0)
1393 return pyepoll_err_closed();
1394 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001395}
1396
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001397
Tal Einat6dc57e22018-06-30 23:02:48 +03001398/*[clinic input]
1399@classmethod
1400select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001401
Tal Einat6dc57e22018-06-30 23:02:48 +03001402 fd: int
1403 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001404
Tal Einat6dc57e22018-06-30 23:02:48 +03001405Create an epoll object from a given control fd.
1406[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001407
1408static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001409select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1410/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1411{
1412 SOCKET s_fd = (SOCKET)fd;
1413 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1414}
1415
1416
1417static PyObject *
1418pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 struct epoll_event ev;
1421 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 if (epfd < 0)
1424 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425
Guido van Rossumee07b942013-12-06 17:46:22 -08001426 switch (op) {
1427 case EPOLL_CTL_ADD:
1428 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 ev.events = events;
1430 ev.data.fd = fd;
1431 Py_BEGIN_ALLOW_THREADS
1432 result = epoll_ctl(epfd, op, fd, &ev);
1433 Py_END_ALLOW_THREADS
1434 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001435 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1437 * operation required a non-NULL pointer in event, even
1438 * though this argument is ignored. */
1439 Py_BEGIN_ALLOW_THREADS
1440 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 Py_END_ALLOW_THREADS
1442 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001443 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 result = -1;
1445 errno = EINVAL;
1446 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001449 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 return NULL;
1451 }
1452 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001453}
1454
Tal Einat6dc57e22018-06-30 23:02:48 +03001455/*[clinic input]
1456select.epoll.register
1457
1458 fd: fildes
1459 the target file descriptor of the operation
Anthony Sottiled0518012020-06-23 14:49:56 -07001460 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001461 a bit set composed of the various EPOLL constants
1462
1463Registers a new fd or raises an OSError if the fd is already registered.
1464
1465The epoll interface supports all file descriptors that support poll.
1466[clinic start generated code]*/
1467
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001468static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001469select_epoll_register_impl(pyEpoll_Object *self, int fd,
1470 unsigned int eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -07001471/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001472{
Tal Einat6dc57e22018-06-30 23:02:48 +03001473 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474}
1475
Tal Einat6dc57e22018-06-30 23:02:48 +03001476/*[clinic input]
1477select.epoll.modify
1478
1479 fd: fildes
1480 the target file descriptor of the operation
1481 eventmask: unsigned_int(bitwise=True)
1482 a bit set composed of the various EPOLL constants
1483
1484Modify event mask for a registered file descriptor.
1485[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001486
1487static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001488select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1489 unsigned int eventmask)
1490/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001491{
Tal Einat6dc57e22018-06-30 23:02:48 +03001492 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001493}
1494
Tal Einat6dc57e22018-06-30 23:02:48 +03001495/*[clinic input]
1496select.epoll.unregister
1497
1498 fd: fildes
1499 the target file descriptor of the operation
1500
1501Remove a registered file descriptor from the epoll object.
1502[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001503
1504static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001505select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1506/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507{
Tal Einat6dc57e22018-06-30 23:02:48 +03001508 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509}
1510
Tal Einat6dc57e22018-06-30 23:02:48 +03001511/*[clinic input]
1512select.epoll.poll
1513
1514 timeout as timeout_obj: object = None
1515 the maximum time to wait in seconds (as float);
1516 a timeout of None or -1 makes poll wait indefinitely
1517 maxevents: int = -1
1518 the maximum number of events returned; -1 means no limit
1519
1520Wait for events on the epoll file descriptor.
1521
1522Returns a list containing any descriptors that have events to report,
1523as a list of (fd, events) 2-tuples.
1524[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001525
1526static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001527select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1528 int maxevents)
1529/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 int nfds, i;
1532 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001533 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001534 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 if (self->epfd < 0)
1537 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001538
Berker Peksagb690b9b2018-09-11 20:29:48 +03001539 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001540 /* epoll_wait() has a resolution of 1 millisecond, round towards
1541 infinity to wait at least timeout seconds. */
1542 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001543 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001544 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1545 PyErr_SetString(PyExc_TypeError,
1546 "timeout must be an integer or None");
1547 }
1548 return NULL;
1549 }
1550
1551 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1552 if (ms < INT_MIN || ms > INT_MAX) {
1553 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1554 return NULL;
1555 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001556 /* epoll_wait(2) treats all arbitrary negative numbers the same
1557 for the timeout argument, but -1 is the documented way to block
1558 indefinitely in the epoll_wait(2) documentation, so we set ms
1559 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001560
Berker Peksagb690b9b2018-09-11 20:29:48 +03001561 Note that we didn't use INFTIM here since it's non-standard and
1562 isn't available under Linux. */
1563 if (ms < 0) {
1564 ms = -1;
1565 }
1566
1567 if (timeout >= 0) {
1568 deadline = _PyTime_GetMonotonicClock() + timeout;
1569 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001573 maxevents = FD_SETSIZE-1;
1574 }
1575 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 PyErr_Format(PyExc_ValueError,
1577 "maxevents must be greater than 0, got %d",
1578 maxevents);
1579 return NULL;
1580 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001581
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001582 evs = PyMem_New(struct epoll_event, maxevents);
1583 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001584 PyErr_NoMemory();
1585 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587
Victor Stinner41eba222015-03-30 21:59:21 +02001588 do {
1589 Py_BEGIN_ALLOW_THREADS
1590 errno = 0;
1591 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1592 Py_END_ALLOW_THREADS
1593
1594 if (errno != EINTR)
1595 break;
1596
1597 /* poll() was interrupted by a signal */
1598 if (PyErr_CheckSignals())
1599 goto error;
1600
1601 if (timeout >= 0) {
1602 timeout = deadline - _PyTime_GetMonotonicClock();
1603 if (timeout < 0) {
1604 nfds = 0;
1605 break;
1606 }
1607 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1608 /* retry epoll_wait() with the recomputed timeout */
1609 }
1610 } while(1);
1611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001613 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 goto error;
1615 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 elist = PyList_New(nfds);
1618 if (elist == NULL) {
1619 goto error;
1620 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001623 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 if (etuple == NULL) {
1625 Py_CLEAR(elist);
1626 goto error;
1627 }
1628 PyList_SET_ITEM(elist, i, etuple);
1629 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630
Christian Heimesf6cd9672008-03-26 13:45:42 +00001631 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001632 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634}
1635
Tal Einat6dc57e22018-06-30 23:02:48 +03001636
1637/*[clinic input]
1638select.epoll.__enter__
1639
1640[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001641
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001642static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001643select_epoll___enter___impl(pyEpoll_Object *self)
1644/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001645{
1646 if (self->epfd < 0)
1647 return pyepoll_err_closed();
1648
1649 Py_INCREF(self);
1650 return (PyObject *)self;
1651}
1652
Tal Einat6dc57e22018-06-30 23:02:48 +03001653/*[clinic input]
1654select.epoll.__exit__
1655
1656 exc_type: object = None
1657 exc_value: object = None
1658 exc_tb: object = None
1659 /
1660
1661[clinic start generated code]*/
1662
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001663static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001664select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1665 PyObject *exc_value, PyObject *exc_tb)
1666/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001667{
Christian Heimesea97eba2020-11-21 20:29:26 +01001668 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
1669 return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001670}
1671
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001672static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 {"closed", (getter)pyepoll_get_closed, NULL,
1674 "True if the epoll handler is closed"},
1675 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001676};
1677
Dino Viehlandf9190542019-09-14 15:20:27 +01001678PyDoc_STRVAR(pyepoll_doc,
1679"select.epoll(sizehint=-1, flags=0)\n\
1680\n\
1681Returns an epolling object\n\
1682\n\
1683sizehint must be a positive integer or -1 for the default size. The\n\
1684sizehint is used to optimize internal data structures. It doesn't limit\n\
1685the maximum number of monitored events.");
1686
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001687#endif /* HAVE_EPOLL */
1688
1689#ifdef HAVE_KQUEUE
1690/* **************************************************************************
1691 * kqueue interface for BSD
1692 *
1693 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1694 * All rights reserved.
1695 *
1696 * Redistribution and use in source and binary forms, with or without
1697 * modification, are permitted provided that the following conditions
1698 * are met:
1699 * 1. Redistributions of source code must retain the above copyright
1700 * notice, this list of conditions and the following disclaimer.
1701 * 2. Redistributions in binary form must reproduce the above copyright
1702 * notice, this list of conditions and the following disclaimer in the
1703 * documentation and/or other materials provided with the distribution.
1704 *
1705 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1706 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1707 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1708 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1709 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1710 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1711 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1712 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1713 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1714 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1715 * SUCH DAMAGE.
1716 */
1717
1718#ifdef HAVE_SYS_EVENT_H
1719#include <sys/event.h>
1720#endif
1721
1722PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001723"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001724\n\
1725This object is the equivalent of the struct kevent for the C API.\n\
1726\n\
1727See the kqueue manpage for more detailed information about the meaning\n\
1728of the arguments.\n\
1729\n\
1730One minor note: while you might hope that udata could store a\n\
1731reference to a python object, it cannot, because it is impossible to\n\
1732keep a proper reference count of the object once it's passed into the\n\
1733kernel. Therefore, I have restricted it to only storing an integer. I\n\
1734recommend ignoring it and simply using the 'ident' field to key off\n\
1735of. You could also set up a dictionary on the python side to store a\n\
1736udata->object mapping.");
1737
1738typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 PyObject_HEAD
1740 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741} kqueue_event_Object;
1742
Christian Heimesea97eba2020-11-21 20:29:26 +01001743#define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001744
1745typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 PyObject_HEAD
1747 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001748} kqueue_queue_Object;
1749
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001750#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1751# error uintptr_t does not match void *!
1752#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1753# define T_UINTPTRT T_ULONGLONG
1754# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001755# define UINTPTRT_FMT_UNIT "K"
1756# define INTPTRT_FMT_UNIT "L"
1757#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1758# define T_UINTPTRT T_ULONG
1759# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001760# define UINTPTRT_FMT_UNIT "k"
1761# define INTPTRT_FMT_UNIT "l"
1762#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1763# define T_UINTPTRT T_UINT
1764# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001765# define UINTPTRT_FMT_UNIT "I"
1766# define INTPTRT_FMT_UNIT "i"
1767#else
1768# error uintptr_t does not match int, long, or long long!
1769#endif
1770
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001771#if SIZEOF_LONG_LONG == 8
1772# define T_INT64 T_LONGLONG
1773# define INT64_FMT_UNIT "L"
1774#elif SIZEOF_LONG == 8
1775# define T_INT64 T_LONG
1776# define INT64_FMT_UNIT "l"
1777#elif SIZEOF_INT == 8
1778# define T_INT64 T_INT
1779# define INT64_FMT_UNIT "i"
1780#else
1781# define INT64_FMT_UNIT "_"
1782#endif
1783
1784#if SIZEOF_LONG_LONG == 4
1785# define T_UINT32 T_ULONGLONG
1786# define UINT32_FMT_UNIT "K"
1787#elif SIZEOF_LONG == 4
1788# define T_UINT32 T_ULONG
1789# define UINT32_FMT_UNIT "k"
1790#elif SIZEOF_INT == 4
1791# define T_UINT32 T_UINT
1792# define UINT32_FMT_UNIT "I"
1793#else
1794# define UINT32_FMT_UNIT "_"
1795#endif
1796
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001797/*
1798 * kevent is not standard and its members vary across BSDs.
1799 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001800#ifdef __NetBSD__
1801# define FILTER_TYPE T_UINT32
1802# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1803# define FLAGS_TYPE T_UINT32
1804# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1805# define FFLAGS_TYPE T_UINT32
1806# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001807#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001808# define FILTER_TYPE T_SHORT
1809# define FILTER_FMT_UNIT "h"
1810# define FLAGS_TYPE T_USHORT
1811# define FLAGS_FMT_UNIT "H"
1812# define FFLAGS_TYPE T_UINT
1813# define FFLAGS_FMT_UNIT "I"
1814#endif
1815
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001816#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001817# define DATA_TYPE T_INT64
1818# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001819#else
1820# define DATA_TYPE T_INTPTRT
1821# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001822#endif
1823
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001824/* Unfortunately, we can't store python objects in udata, because
1825 * kevents in the kernel can be removed without warning, which would
1826 * forever lose the refcount on the object stored with it.
1827 */
1828
1829#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1830static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001831 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1832 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1833 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001835 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1837 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001838};
1839#undef KQ_OFF
1840
1841static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001842
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001843kqueue_event_repr(kqueue_event_Object *s)
1844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 char buf[1024];
1846 PyOS_snprintf(
1847 buf, sizeof(buf),
1848 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001849 "data=0x%llx udata=%p>",
1850 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1851 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853}
1854
1855static int
1856kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 PyObject *pfd;
1859 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1860 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001861 static const char fmt[] = "O|"
1862 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1863 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1868 &pfd, &(self->e.filter), &(self->e.flags),
1869 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1870 return -1;
1871 }
1872
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001873 if (PyLong_Check(pfd)) {
1874 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 }
1876 else {
1877 self->e.ident = PyObject_AsFileDescriptor(pfd);
1878 }
1879 if (PyErr_Occurred()) {
1880 return -1;
1881 }
1882 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883}
1884
1885static PyObject *
1886kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001888{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001889 int result;
Christian Heimesea97eba2020-11-21 20:29:26 +01001890 _selectstate *state = _selectstate_by_type(Py_TYPE(s));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891
Christian Heimesea97eba2020-11-21 20:29:26 +01001892 if (!kqueue_event_Check(o, state)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001893 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001895
1896#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1897 result = CMP(s->e.ident, o->e.ident)
1898 : CMP(s->e.filter, o->e.filter)
1899 : CMP(s->e.flags, o->e.flags)
1900 : CMP(s->e.fflags, o->e.fflags)
1901 : CMP(s->e.data, o->e.data)
1902 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1903 : 0;
1904#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001905
stratakise8b19652017-11-02 11:32:54 +01001906 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001907}
1908
Dino Viehlandf9190542019-09-14 15:20:27 +01001909static PyType_Slot kqueue_event_Type_slots[] = {
1910 {Py_tp_doc, (void*)kqueue_event_doc},
1911 {Py_tp_init, kqueue_event_init},
1912 {Py_tp_members, kqueue_event_members},
1913 {Py_tp_new, PyType_GenericNew},
1914 {Py_tp_repr, kqueue_event_repr},
1915 {Py_tp_richcompare, kqueue_event_richcompare},
1916 {0, 0},
1917};
1918
1919static PyType_Spec kqueue_event_Type_spec = {
1920 "select.kevent",
1921 sizeof(kqueue_event_Object),
1922 0,
1923 Py_TPFLAGS_DEFAULT,
1924 kqueue_event_Type_slots
1925};
1926
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001927static PyObject *
1928kqueue_queue_err_closed(void)
1929{
Victor Stinner13423c32013-08-22 00:19:50 +02001930 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001932}
1933
1934static int
1935kqueue_queue_internal_close(kqueue_queue_Object *self)
1936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 int save_errno = 0;
1938 if (self->kqfd >= 0) {
1939 int kqfd = self->kqfd;
1940 self->kqfd = -1;
1941 Py_BEGIN_ALLOW_THREADS
1942 if (close(kqfd) < 0)
1943 save_errno = errno;
1944 Py_END_ALLOW_THREADS
1945 }
1946 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001947}
1948
1949static PyObject *
1950newKqueue_Object(PyTypeObject *type, SOCKET fd)
1951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001953 assert(type != NULL);
1954 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1955 assert(queue_alloc != NULL);
1956 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 if (self == NULL) {
1958 return NULL;
1959 }
1960
1961 if (fd == -1) {
1962 Py_BEGIN_ALLOW_THREADS
1963 self->kqfd = kqueue();
1964 Py_END_ALLOW_THREADS
1965 }
1966 else {
1967 self->kqfd = fd;
1968 }
1969 if (self->kqfd < 0) {
1970 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001971 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 return NULL;
1973 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001974
1975 if (fd == -1) {
1976 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1977 Py_DECREF(self);
1978 return NULL;
1979 }
1980 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001982}
1983
Tal Einat6dc57e22018-06-30 23:02:48 +03001984/*[clinic input]
1985@classmethod
1986select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001987
Tal Einat6dc57e22018-06-30 23:02:48 +03001988Kqueue syscall wrapper.
1989
1990For example, to start watching a socket for input:
1991>>> kq = kqueue()
1992>>> sock = socket()
1993>>> sock.connect((host, port))
1994>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1995
1996To wait one second for it to become writeable:
1997>>> kq.control(None, 1, 1000)
1998
1999To stop listening:
2000>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2001[clinic start generated code]*/
2002
2003static PyObject *
2004select_kqueue_impl(PyTypeObject *type)
2005/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2006{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002008}
2009
2010static void
2011kqueue_queue_dealloc(kqueue_queue_Object *self)
2012{
Dino Viehlandf9190542019-09-14 15:20:27 +01002013 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002015 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2016 kqueue_free((PyObject *)self);
2017 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002018}
2019
Tal Einat6dc57e22018-06-30 23:02:48 +03002020/*[clinic input]
2021select.kqueue.close
2022
2023Close the kqueue control file descriptor.
2024
2025Further operations on the kqueue object will raise an exception.
2026[clinic start generated code]*/
2027
2028static PyObject *
2029select_kqueue_close_impl(kqueue_queue_Object *self)
2030/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 errno = kqueue_queue_internal_close(self);
2033 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002034 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 return NULL;
2036 }
2037 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002038}
2039
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002041kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002042{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 if (self->kqfd < 0)
2044 Py_RETURN_TRUE;
2045 else
2046 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002047}
2048
Tal Einat6dc57e22018-06-30 23:02:48 +03002049/*[clinic input]
2050select.kqueue.fileno
2051
2052Return the kqueue control file descriptor.
2053[clinic start generated code]*/
2054
2055static PyObject *
2056select_kqueue_fileno_impl(kqueue_queue_Object *self)
2057/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 if (self->kqfd < 0)
2060 return kqueue_queue_err_closed();
2061 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002062}
2063
Tal Einat6dc57e22018-06-30 23:02:48 +03002064/*[clinic input]
2065@classmethod
2066select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002067
Tal Einat6dc57e22018-06-30 23:02:48 +03002068 fd: int
2069 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002070
Tal Einat6dc57e22018-06-30 23:02:48 +03002071Create a kqueue object from a given control fd.
2072[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002073
2074static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002075select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2076/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002077{
Tal Einat6dc57e22018-06-30 23:02:48 +03002078 SOCKET s_fd = (SOCKET)fd;
2079
2080 return newKqueue_Object(type, s_fd);
2081}
2082
2083/*[clinic input]
2084select.kqueue.control
2085
2086 changelist: object
2087 Must be an iterable of kevent objects describing the changes to be made
2088 to the kernel's watch list or None.
2089 maxevents: int
2090 The maximum number of events that the kernel will return.
2091 timeout as otimeout: object = None
2092 The maximum time to wait in seconds, or else None to wait forever.
2093 This accepts floats for smaller timeouts, too.
2094 /
2095
2096Calls the kernel kevent function.
2097[clinic start generated code]*/
2098
2099static PyObject *
2100select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2101 int maxevents, PyObject *otimeout)
2102/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 int gotevents = 0;
2105 int nchanges = 0;
2106 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002107 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 PyObject *result = NULL;
2109 struct kevent *evl = NULL;
2110 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002111 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002113 _PyTime_t timeout, deadline = 0;
Christian Heimesea97eba2020-11-21 20:29:26 +01002114 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 if (self->kqfd < 0)
2117 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002118
Tal Einat6dc57e22018-06-30 23:02:48 +03002119 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 PyErr_Format(PyExc_ValueError,
2121 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002122 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 return NULL;
2124 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002125
Tal Einat6dc57e22018-06-30 23:02:48 +03002126 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 ptimeoutspec = NULL;
2128 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002129 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002130 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002131 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002132 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002133 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002134 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002135 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002136 return NULL;
2137 }
2138
Victor Stinner4448c082015-03-31 11:48:34 +02002139 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002140 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002141
Victor Stinner4448c082015-03-31 11:48:34 +02002142 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 PyErr_SetString(PyExc_ValueError,
2144 "timeout must be positive or None");
2145 return NULL;
2146 }
Victor Stinner4448c082015-03-31 11:48:34 +02002147 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002149
Tal Einat6dc57e22018-06-30 23:02:48 +03002150 if (changelist != Py_None) {
2151 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002152 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 return NULL;
2154 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002155 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2156 PyErr_SetString(PyExc_OverflowError,
2157 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 goto error;
2159 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002160 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 chl = PyMem_New(struct kevent, nchanges);
2163 if (chl == NULL) {
2164 PyErr_NoMemory();
2165 goto error;
2166 }
Christian Heimesea97eba2020-11-21 20:29:26 +01002167 _selectstate *state = _selectstate_by_type(Py_TYPE(self));
Serhiy Storchakade072102017-10-12 22:17:46 +03002168 for (i = 0; i < nchanges; ++i) {
2169 ei = PySequence_Fast_GET_ITEM(seq, i);
Christian Heimesea97eba2020-11-21 20:29:26 +01002170 if (!kqueue_event_Check(ei, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 PyErr_SetString(PyExc_TypeError,
2172 "changelist must be an iterable of "
2173 "select.kevent objects");
2174 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002176 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002178 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002182 if (maxevents) {
2183 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 if (evl == NULL) {
2185 PyErr_NoMemory();
2186 goto error;
2187 }
2188 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002189
Victor Stinner4448c082015-03-31 11:48:34 +02002190 if (ptimeoutspec)
2191 deadline = _PyTime_GetMonotonicClock() + timeout;
2192
2193 do {
2194 Py_BEGIN_ALLOW_THREADS
2195 errno = 0;
2196 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002197 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002198 Py_END_ALLOW_THREADS
2199
2200 if (errno != EINTR)
2201 break;
2202
2203 /* kevent() was interrupted by a signal */
2204 if (PyErr_CheckSignals())
2205 goto error;
2206
2207 if (ptimeoutspec) {
2208 timeout = deadline - _PyTime_GetMonotonicClock();
2209 if (timeout < 0) {
2210 gotevents = 0;
2211 break;
2212 }
2213 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2214 goto error;
2215 /* retry kevent() with the recomputed timeout */
2216 }
2217 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 if (gotevents == -1) {
2220 PyErr_SetFromErrno(PyExc_OSError);
2221 goto error;
2222 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 result = PyList_New(gotevents);
2225 if (result == NULL) {
2226 goto error;
2227 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 for (i = 0; i < gotevents; i++) {
2230 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Christian Heimesea97eba2020-11-21 20:29:26 +01002232 ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 if (ch == NULL) {
2234 goto error;
2235 }
2236 ch->e = evl[i];
2237 PyList_SET_ITEM(result, i, (PyObject *)ch);
2238 }
2239 PyMem_Free(chl);
2240 PyMem_Free(evl);
2241 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242
2243 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 PyMem_Free(chl);
2245 PyMem_Free(evl);
2246 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002247 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002249}
2250
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002251static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 {"closed", (getter)kqueue_queue_get_closed, NULL,
2253 "True if the kqueue handler is closed"},
2254 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255};
2256
Tal Einat6dc57e22018-06-30 23:02:48 +03002257#endif /* HAVE_KQUEUE */
2258
2259
2260/* ************************************************************************ */
2261
2262#include "clinic/selectmodule.c.h"
2263
2264#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2265
2266static PyMethodDef poll_methods[] = {
2267 SELECT_POLL_REGISTER_METHODDEF
2268 SELECT_POLL_MODIFY_METHODDEF
2269 SELECT_POLL_UNREGISTER_METHODDEF
2270 SELECT_POLL_POLL_METHODDEF
2271 {NULL, NULL} /* sentinel */
2272};
2273
Dino Viehlandf9190542019-09-14 15:20:27 +01002274
2275static PyType_Slot poll_Type_slots[] = {
2276 {Py_tp_dealloc, poll_dealloc},
2277 {Py_tp_methods, poll_methods},
2278 {Py_tp_new, poll_new},
2279 {0, 0},
2280};
2281
2282static PyType_Spec poll_Type_spec = {
2283 "select.poll",
2284 sizeof(pollObject),
2285 0,
2286 Py_TPFLAGS_DEFAULT,
2287 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002288};
2289
2290#ifdef HAVE_SYS_DEVPOLL_H
2291
2292static PyMethodDef devpoll_methods[] = {
2293 SELECT_DEVPOLL_REGISTER_METHODDEF
2294 SELECT_DEVPOLL_MODIFY_METHODDEF
2295 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2296 SELECT_DEVPOLL_POLL_METHODDEF
2297 SELECT_DEVPOLL_CLOSE_METHODDEF
2298 SELECT_DEVPOLL_FILENO_METHODDEF
2299 {NULL, NULL} /* sentinel */
2300};
2301
Tal Einat6dc57e22018-06-30 23:02:48 +03002302#endif /* HAVE_SYS_DEVPOLL_H */
2303
2304#endif /* HAVE_POLL */
2305
2306#ifdef HAVE_EPOLL
2307
2308static PyMethodDef pyepoll_methods[] = {
2309 SELECT_EPOLL_FROMFD_METHODDEF
2310 SELECT_EPOLL_CLOSE_METHODDEF
2311 SELECT_EPOLL_FILENO_METHODDEF
2312 SELECT_EPOLL_MODIFY_METHODDEF
2313 SELECT_EPOLL_REGISTER_METHODDEF
2314 SELECT_EPOLL_UNREGISTER_METHODDEF
2315 SELECT_EPOLL_POLL_METHODDEF
2316 SELECT_EPOLL___ENTER___METHODDEF
2317 SELECT_EPOLL___EXIT___METHODDEF
2318 {NULL, NULL},
2319};
2320
Dino Viehlandf9190542019-09-14 15:20:27 +01002321static PyType_Slot pyEpoll_Type_slots[] = {
2322 {Py_tp_dealloc, pyepoll_dealloc},
2323 {Py_tp_doc, (void*)pyepoll_doc},
2324 {Py_tp_getattro, PyObject_GenericGetAttr},
2325 {Py_tp_getset, pyepoll_getsetlist},
2326 {Py_tp_methods, pyepoll_methods},
2327 {Py_tp_new, select_epoll},
2328 {0, 0},
2329};
2330
2331static PyType_Spec pyEpoll_Type_spec = {
2332 "select.epoll",
2333 sizeof(pyEpoll_Object),
2334 0,
2335 Py_TPFLAGS_DEFAULT,
2336 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002337};
2338
2339#endif /* HAVE_EPOLL */
2340
2341#ifdef HAVE_KQUEUE
2342
Tal Einat6dc57e22018-06-30 23:02:48 +03002343static PyMethodDef kqueue_queue_methods[] = {
2344 SELECT_KQUEUE_FROMFD_METHODDEF
2345 SELECT_KQUEUE_CLOSE_METHODDEF
2346 SELECT_KQUEUE_FILENO_METHODDEF
2347 SELECT_KQUEUE_CONTROL_METHODDEF
2348 {NULL, NULL},
2349};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002350
Dino Viehlandf9190542019-09-14 15:20:27 +01002351static PyType_Slot kqueue_queue_Type_slots[] = {
2352 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002353 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002354 {Py_tp_getset, kqueue_queue_getsetlist},
2355 {Py_tp_methods, kqueue_queue_methods},
2356 {Py_tp_new, select_kqueue},
2357 {0, 0},
2358};
2359
2360static PyType_Spec kqueue_queue_Type_spec = {
2361 "select.kqueue",
2362 sizeof(kqueue_queue_Object),
2363 0,
2364 Py_TPFLAGS_DEFAULT,
2365 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002366};
2367
2368#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002369
2370
2371
2372
2373
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002374/* ************************************************************************ */
2375
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002376
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002377static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002378 SELECT_SELECT_METHODDEF
2379 SELECT_POLL_METHODDEF
2380 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002382};
2383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002385"This module supports asynchronous I/O on multiple file descriptors.\n\
2386\n\
2387*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002388On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002389
Martin v. Löwis1a214512008-06-11 05:26:20 +00002390
Dino Viehlandf9190542019-09-14 15:20:27 +01002391
2392static int
2393_select_traverse(PyObject *module, visitproc visit, void *arg)
2394{
Christian Heimesea97eba2020-11-21 20:29:26 +01002395 _selectstate *state = get_select_state(module);
2396
2397 Py_VISIT(state->close);
2398 Py_VISIT(state->poll_Type);
2399 Py_VISIT(state->devpoll_Type);
2400 Py_VISIT(state->pyEpoll_Type);
2401 Py_VISIT(state->kqueue_event_Type);
2402 Py_VISIT(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002403 return 0;
2404}
2405
2406static int
2407_select_clear(PyObject *module)
2408{
Christian Heimesea97eba2020-11-21 20:29:26 +01002409 _selectstate *state = get_select_state(module);
2410
2411 Py_CLEAR(state->close);
2412 Py_CLEAR(state->poll_Type);
2413 Py_CLEAR(state->devpoll_Type);
2414 Py_CLEAR(state->pyEpoll_Type);
2415 Py_CLEAR(state->kqueue_event_Type);
2416 Py_CLEAR(state->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002417 return 0;
2418}
2419
2420static void
2421_select_free(void *module)
2422{
2423 _select_clear((PyObject *)module);
2424}
2425
Christian Heimesea97eba2020-11-21 20:29:26 +01002426int
2427_select_exec(PyObject *m)
Guido van Rossumed233a51992-06-23 09:07:03 +00002428{
Christian Heimesea97eba2020-11-21 20:29:26 +01002429 _selectstate *state = get_select_state(m);
Fred Drake4baedc12002-04-01 14:53:37 +00002430
Christian Heimesea97eba2020-11-21 20:29:26 +01002431 state->close = PyUnicode_InternFromString("close");
2432 if (state->close == NULL) {
2433 return -1;
2434 }
2435 if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
2436 return -1;
2437 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002438
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002439#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002440#ifdef HAVE_BROKEN_PIPE_BUF
2441#undef PIPE_BUF
2442#define PIPE_BUF 512
2443#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002444 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002445#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002446
Charles-François Natali986a56c2013-01-19 12:19:10 +01002447#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002448#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449 if (select_have_broken_poll()) {
2450 if (PyObject_DelAttrString(m, "poll") == -1) {
2451 PyErr_Clear();
2452 }
2453 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002454#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002456#endif
Christian Heimesea97eba2020-11-21 20:29:26 +01002457 state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2458 m, &poll_Type_spec, NULL);
2459 if (state->poll_Type == NULL) {
2460 return -1;
2461 }
Dino Viehlandf9190542019-09-14 15:20:27 +01002462
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002463 PyModule_AddIntMacro(m, POLLIN);
2464 PyModule_AddIntMacro(m, POLLPRI);
2465 PyModule_AddIntMacro(m, POLLOUT);
2466 PyModule_AddIntMacro(m, POLLERR);
2467 PyModule_AddIntMacro(m, POLLHUP);
2468 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002469
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002470#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002471 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002472#endif
2473#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002474 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002475#endif
2476#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002477 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002478#endif
2479#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002480 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002481#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002482#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002483 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002484#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002485#ifdef POLLRDHUP
2486 /* Kernel 2.6.17+ */
2487 PyModule_AddIntMacro(m, POLLRDHUP);
2488#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002490#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002491
Jesus Cead8b9ae62011-11-14 19:07:41 +01002492#ifdef HAVE_SYS_DEVPOLL_H
Christian Heimesea97eba2020-11-21 20:29:26 +01002493 state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2494 m, &devpoll_Type_spec, NULL);
2495 if (state->devpoll_Type == NULL) {
2496 return -1;
2497 }
Jesus Cead8b9ae62011-11-14 19:07:41 +01002498#endif
2499
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002500#ifdef HAVE_EPOLL
Christian Heimesea97eba2020-11-21 20:29:26 +01002501 state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2502 m, &pyEpoll_Type_spec, NULL);
2503 if (state->pyEpoll_Type == NULL) {
2504 return -1;
2505 }
2506 if (PyModule_AddType(m, state->pyEpoll_Type) < 0) {
2507 return -1;
2508 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002509
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002510 PyModule_AddIntMacro(m, EPOLLIN);
2511 PyModule_AddIntMacro(m, EPOLLOUT);
2512 PyModule_AddIntMacro(m, EPOLLPRI);
2513 PyModule_AddIntMacro(m, EPOLLERR);
2514 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002515#ifdef EPOLLRDHUP
2516 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002517 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002518#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002519 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002520#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002522 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002523#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002524#ifdef EPOLLEXCLUSIVE
2525 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2526#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002527
2528#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002529 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002530#endif
2531#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002532 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002533#endif
2534#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002535 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002536#endif
2537#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002538 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002539#endif
2540#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002541 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002542#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002543
Benjamin Peterson95c16622011-12-27 15:36:32 -06002544#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002545 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002546#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002547#endif /* HAVE_EPOLL */
2548
2549#ifdef HAVE_KQUEUE
Christian Heimesea97eba2020-11-21 20:29:26 +01002550 state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2551 m, &kqueue_event_Type_spec, NULL);
2552 if (state->kqueue_event_Type == NULL) {
2553 return -1;
2554 }
2555 if (PyModule_AddType(m, state->kqueue_event_Type) < 0) {
2556 return -1;
2557 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002558
Christian Heimesea97eba2020-11-21 20:29:26 +01002559 state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2560 m, &kqueue_queue_Type_spec, NULL);
2561 if (state->kqueue_queue_Type == NULL) {
2562 return -1;
2563 }
2564 if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) {
2565 return -1;
2566 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002567
2568 /* event filters */
2569 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2570 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002571#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
2574#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
2577#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002579#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002580#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002582#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002583#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002585#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 /* event flags */
2589 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2590 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2591 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2592 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2593 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2594 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002595
Berker Peksag7ec64562016-09-14 18:16:59 +03002596#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#endif
2599#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002601#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002603 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2604 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002607#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002609#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002612#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2615 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2616 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2617 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2618 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2619 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002623#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2625 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2626 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2627 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2628 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2631 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2632 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002633#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634
2635 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002636#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2638 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2639 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002640#endif
2641
2642#endif /* HAVE_KQUEUE */
Christian Heimesea97eba2020-11-21 20:29:26 +01002643 return 0;
2644}
2645
2646static PyModuleDef_Slot _select_slots[] = {
2647 {Py_mod_exec, _select_exec},
2648 {0, NULL}
2649};
2650
2651static struct PyModuleDef selectmodule = {
2652 PyModuleDef_HEAD_INIT,
2653 .m_name = "select",
2654 .m_doc = module_doc,
2655 .m_size = sizeof(_selectstate),
2656 .m_methods = select_methods,
2657 .m_slots = _select_slots,
2658 .m_traverse = _select_traverse,
2659 .m_clear = _select_clear,
2660 .m_free = _select_free,
2661};
2662
2663PyMODINIT_FUNC
2664PyInit_select(void)
2665{
2666 return PyModuleDef_Init(&selectmodule);
Guido van Rossumed233a51992-06-23 09:07:03 +00002667}