blob: fe852f93c37d1dd99d20de968d812b74df7bdb42 [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Berker Peksagfe8d9662016-07-19 21:09:26 +03007#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
8#define _GNU_SOURCE
9#endif
10
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000011#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020012#include "structmember.h" // PyMemberDef
Guido van Rossumed233a51992-06-23 09:07:03 +000013
Jesus Cead8b9ae62011-11-14 19:07:41 +010014#ifdef HAVE_SYS_DEVPOLL_H
15#include <sys/resource.h>
16#include <sys/devpoll.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#endif
21
Thomas Wouters477c8d52006-05-27 19:21:47 +000022#ifdef __APPLE__
23 /* Perform runtime testing for a broken poll on OSX to make it easier
24 * to use the same binary on multiple releases of the OS.
25 */
26#undef HAVE_BROKEN_POLL
27#endif
28
Tim Petersd92dfe02000-12-12 01:18:41 +000029/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
30 64 is too small (too many people have bumped into that limit).
31 Here we boost it.
32 Users who want even more than the boosted limit should #define
33 FD_SETSIZE higher before this; e.g., via compiler /D switch.
34*/
35#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
36#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000038
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000039#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000040#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000041#elif defined(HAVE_SYS_POLL_H)
42#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000043#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000044
Guido van Rossum37273171996-12-09 18:47:43 +000045#ifdef __sgi
46/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000047extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000048#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000052#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053
Guido van Rossum6f489d91996-06-28 20:15:15 +000054#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000055# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000057#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000059#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000060
Dino Viehlandf9190542019-09-14 15:20:27 +010061typedef struct {
62 PyObject *close;
63 PyTypeObject *poll_Type;
64 PyTypeObject *devpoll_Type;
65 PyTypeObject *pyEpoll_Type;
66 PyTypeObject *kqueue_event_Type;
67 PyTypeObject *kqueue_queue_Type;
68} _selectstate;
69
70static struct PyModuleDef selectmodule;
71
Hai Shif707d942020-03-16 21:15:01 +080072static inline _selectstate*
73get_select_state(PyObject *module)
74{
75 void *state = PyModule_GetState(module);
76 assert(state != NULL);
77 return (_selectstate *)state;
78}
79
80#define _selectstate_global get_select_state(PyState_FindModule(&selectmodule))
Dino Viehlandf9190542019-09-14 15:20:27 +010081
Tal Einat6dc57e22018-06-30 23:02:48 +030082/*[clinic input]
83module select
84class select.poll "pollObject *" "&poll_Type"
85class select.devpoll "devpollObject *" "&devpoll_Type"
86class select.epoll "pyEpoll_Object *" "&pyEpoll_Type"
Dino Viehlandf9190542019-09-14 15:20:27 +010087class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_Type"
Tal Einat6dc57e22018-06-30 23:02:48 +030088[clinic start generated code]*/
Dino Viehlandf9190542019-09-14 15:20:27 +010089/*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/
Tal Einat6dc57e22018-06-30 23:02:48 +030090
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) {
297 if (rfd2obj) PyMem_DEL(rfd2obj);
298 if (wfd2obj) PyMem_DEL(wfd2obj);
299 if (efd2obj) PyMem_DEL(efd2obj);
300 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 PyMem_DEL(rfd2obj);
385 PyMem_DEL(wfd2obj);
386 PyMem_DEL(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 Storchakaa24107b2019-02-25 17:59:46 +0200502 if (PyDict_GetItemWithError(self->dict, key) == NULL) {
503 if (!PyErr_Occurred()) {
504 errno = ENOENT;
505 PyErr_SetFromErrno(PyExc_OSError);
506 }
Jesus Cea62a5c322012-07-19 21:31:26 +0200507 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 return NULL;
509 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300510 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (value == NULL) {
512 Py_DECREF(key);
513 return NULL;
514 }
515 err = PyDict_SetItem(self->dict, key, value);
516 Py_DECREF(key);
517 Py_DECREF(value);
518 if (err < 0)
519 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 self->ufd_uptodate = 0;
522
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200523 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000524}
525
526
Tal Einat6dc57e22018-06-30 23:02:48 +0300527/*[clinic input]
528select.poll.unregister
529
530 fd: fildes
531 /
532
533Remove a file descriptor being tracked by the polling object.
534[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000535
536static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300537select_poll_unregister_impl(pollObject *self, int fd)
538/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 /* Check whether the fd is already in the array */
543 key = PyLong_FromLong(fd);
544 if (key == NULL)
545 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 if (PyDict_DelItem(self->dict, key) == -1) {
548 Py_DECREF(key);
549 /* This will simply raise the KeyError set by PyDict_DelItem
550 if the file descriptor isn't registered. */
551 return NULL;
552 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 Py_DECREF(key);
555 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200557 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558}
559
Tal Einat6dc57e22018-06-30 23:02:48 +0300560/*[clinic input]
561select.poll.poll
562
563 timeout as timeout_obj: object = None
564 /
565
566Polls the set of registered file descriptors.
567
568Returns a list containing any descriptors that have events or errors to
569report, as a list of (fd, event) 2-tuples.
570[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000571
572static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300573select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
574/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000575{
Tal Einat6dc57e22018-06-30 23:02:48 +0300576 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200577 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200579 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200580 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000581
Tal Einat6dc57e22018-06-30 23:02:48 +0300582 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100584 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200585 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
586 PyErr_SetString(PyExc_TypeError,
587 "timeout must be an integer or None");
588 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200590 }
591
Pablo Galindo2c15b292017-10-17 15:14:41 +0100592 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200593 if (ms < INT_MIN || ms > INT_MAX) {
594 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200596 }
597
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200598 if (timeout >= 0) {
599 deadline = _PyTime_GetMonotonicClock() + timeout;
600 }
601 }
602
603 /* On some OSes, typically BSD-based ones, the timeout parameter of the
604 poll() syscall, when negative, must be exactly INFTIM, where defined,
605 or -1. See issue 31334. */
606 if (ms < 0) {
607#ifdef INFTIM
608 ms = INFTIM;
609#else
610 ms = -1;
611#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000613
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300614 /* Avoid concurrent poll() invocation, issue 8865 */
615 if (self->poll_running) {
616 PyErr_SetString(PyExc_RuntimeError,
617 "concurrent poll() invocation");
618 return NULL;
619 }
620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 /* Ensure the ufd array is up to date */
622 if (!self->ufd_uptodate)
623 if (update_ufd_array(self) == 0)
624 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000625
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300626 self->poll_running = 1;
627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200629 async_err = 0;
630 do {
631 Py_BEGIN_ALLOW_THREADS
632 errno = 0;
633 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
634 Py_END_ALLOW_THREADS
635
636 if (errno != EINTR)
637 break;
638
639 /* poll() was interrupted by a signal */
640 if (PyErr_CheckSignals()) {
641 async_err = 1;
642 break;
643 }
644
645 if (timeout >= 0) {
646 timeout = deadline - _PyTime_GetMonotonicClock();
647 if (timeout < 0) {
648 poll_result = 0;
649 break;
650 }
651 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
652 /* retry poll() with the recomputed timeout */
653 }
654 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300656 self->poll_running = 0;
657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200659 if (!async_err)
660 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 return NULL;
662 }
663
664 /* build the result list */
665
666 result_list = PyList_New(poll_result);
667 if (!result_list)
668 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200670 for (i = 0, j = 0; j < poll_result; j++) {
671 /* skip to the next fired descriptor */
672 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 i++;
674 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200675 /* if we hit a NULL return, set value to NULL
676 and break out of loop; code at end will
677 clean up result_list */
678 value = PyTuple_New(2);
679 if (value == NULL)
680 goto error;
681 num = PyLong_FromLong(self->ufds[i].fd);
682 if (num == NULL) {
683 Py_DECREF(value);
684 goto error;
685 }
686 PyTuple_SET_ITEM(value, 0, num);
687
688 /* The &0xffff is a workaround for AIX. 'revents'
689 is a 16-bit short, and IBM assigned POLLNVAL
690 to be 0x8000, so the conversion to int results
691 in a negative number. See SF bug #923315. */
692 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
693 if (num == NULL) {
694 Py_DECREF(value);
695 goto error;
696 }
697 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700698 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200699 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 }
701 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000702
703 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 Py_DECREF(result_list);
705 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000706}
707
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000708static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000709newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000710{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 pollObject *self;
Dino Viehlandf9190542019-09-14 15:20:27 +0100712 self = PyObject_New(pollObject, _selectstate_global->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 if (self == NULL)
714 return NULL;
715 /* ufd_uptodate is a Boolean, denoting whether the
716 array pointed to by ufds matches the contents of the dictionary. */
717 self->ufd_uptodate = 0;
718 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300719 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 self->dict = PyDict_New();
721 if (self->dict == NULL) {
722 Py_DECREF(self);
723 return NULL;
724 }
725 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000726}
727
Dino Viehlandf9190542019-09-14 15:20:27 +0100728static PyObject *
729poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
730{
731 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
732 return NULL;
733}
734
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000735static void
736poll_dealloc(pollObject *self)
737{
Dino Viehlandf9190542019-09-14 15:20:27 +0100738 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 if (self->ufds != NULL)
740 PyMem_DEL(self->ufds);
741 Py_XDECREF(self->dict);
742 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100743 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000744}
745
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000746
Jesus Cead8b9ae62011-11-14 19:07:41 +0100747#ifdef HAVE_SYS_DEVPOLL_H
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300748static PyMethodDef devpoll_methods[];
749
Jesus Cead8b9ae62011-11-14 19:07:41 +0100750typedef struct {
751 PyObject_HEAD
752 int fd_devpoll;
753 int max_n_fds;
754 int n_fds;
755 struct pollfd *fds;
756} devpollObject;
757
Victor Stinner13423c32013-08-22 00:19:50 +0200758static PyObject *
759devpoll_err_closed(void)
760{
761 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
762 return NULL;
763}
764
Jesus Cead8b9ae62011-11-14 19:07:41 +0100765static int devpoll_flush(devpollObject *self)
766{
767 int size, n;
768
769 if (!self->n_fds) return 0;
770
771 size = sizeof(struct pollfd)*self->n_fds;
772 self->n_fds = 0;
773
Victor Stinner54799672015-03-19 23:33:09 +0100774 n = _Py_write(self->fd_devpoll, self->fds, size);
775 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100776 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100777
Jesus Cead8b9ae62011-11-14 19:07:41 +0100778 if (n < size) {
779 /*
780 ** Data writed to /dev/poll is a binary data structure. It is not
781 ** clear what to do if a partial write occurred. For now, raise
782 ** an exception and see if we actually found this problem in
783 ** the wild.
784 ** See http://bugs.python.org/issue6397.
785 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300786 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100787 "Please, report at http://bugs.python.org/. "
788 "Data to report: Size tried: %d, actual size written: %d.",
789 size, n);
790 return -1;
791 }
792 return 0;
793}
794
795static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300796internal_devpoll_register(devpollObject *self, int fd,
797 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100798{
Victor Stinner13423c32013-08-22 00:19:50 +0200799 if (self->fd_devpoll < 0)
800 return devpoll_err_closed();
801
Jesus Cead8b9ae62011-11-14 19:07:41 +0100802 if (remove) {
803 self->fds[self->n_fds].fd = fd;
804 self->fds[self->n_fds].events = POLLREMOVE;
805
806 if (++self->n_fds == self->max_n_fds) {
807 if (devpoll_flush(self))
808 return NULL;
809 }
810 }
811
812 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200813 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100814
815 if (++self->n_fds == self->max_n_fds) {
816 if (devpoll_flush(self))
817 return NULL;
818 }
819
820 Py_RETURN_NONE;
821}
822
Tal Einat6dc57e22018-06-30 23:02:48 +0300823/*[clinic input]
824select.devpoll.register
825
826 fd: fildes
827 either an integer, or an object with a fileno() method returning
828 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700829 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300830 an optional bitmask describing the type of events to check for
831 /
832
833Register a file descriptor with the polling object.
834[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100835
836static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300837select_devpoll_register_impl(devpollObject *self, int fd,
838 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700839/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100840{
Tal Einat6dc57e22018-06-30 23:02:48 +0300841 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100842}
843
Tal Einat6dc57e22018-06-30 23:02:48 +0300844/*[clinic input]
845select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100846
Tal Einat6dc57e22018-06-30 23:02:48 +0300847 fd: fildes
848 either an integer, or an object with a fileno() method returning
849 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700850 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300851 an optional bitmask describing the type of events to check for
852 /
853
854Modify a possible already registered file descriptor.
855[clinic start generated code]*/
856
857static PyObject *
858select_devpoll_modify_impl(devpollObject *self, int fd,
859 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700860/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100861{
Tal Einat6dc57e22018-06-30 23:02:48 +0300862 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863}
864
Tal Einat6dc57e22018-06-30 23:02:48 +0300865/*[clinic input]
866select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100867
Tal Einat6dc57e22018-06-30 23:02:48 +0300868 fd: fildes
869 /
870
871Remove a file descriptor being tracked by the polling object.
872[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100873
874static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300875select_devpoll_unregister_impl(devpollObject *self, int fd)
876/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100877{
Victor Stinner13423c32013-08-22 00:19:50 +0200878 if (self->fd_devpoll < 0)
879 return devpoll_err_closed();
880
Jesus Cead8b9ae62011-11-14 19:07:41 +0100881 self->fds[self->n_fds].fd = fd;
882 self->fds[self->n_fds].events = POLLREMOVE;
883
884 if (++self->n_fds == self->max_n_fds) {
885 if (devpoll_flush(self))
886 return NULL;
887 }
888
889 Py_RETURN_NONE;
890}
891
Tal Einat6dc57e22018-06-30 23:02:48 +0300892/*[clinic input]
893select.devpoll.poll
894 timeout as timeout_obj: object = None
895 /
896
897Polls the set of registered file descriptors.
898
899Returns a list containing any descriptors that have events or errors to
900report, as a list of (fd, event) 2-tuples.
901[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902
903static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300904select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
905/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100906{
907 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200908 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100910 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200911 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912
Victor Stinner13423c32013-08-22 00:19:50 +0200913 if (self->fd_devpoll < 0)
914 return devpoll_err_closed();
915
Jesus Cead8b9ae62011-11-14 19:07:41 +0100916 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300917 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100918 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200919 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920 }
921 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200922 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100923 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200924 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
925 PyErr_SetString(PyExc_TypeError,
926 "timeout must be an integer or None");
927 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200929 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100930
Pablo Galindo2c15b292017-10-17 15:14:41 +0100931 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 if (ms < -1 || ms > INT_MAX) {
933 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
934 return NULL;
935 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100936 }
937
938 if (devpoll_flush(self))
939 return NULL;
940
941 dvp.dp_fds = self->fds;
942 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200943 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100944
Victor Stinner45ca48b2015-03-31 12:10:33 +0200945 if (timeout >= 0)
946 deadline = _PyTime_GetMonotonicClock() + timeout;
947
948 do {
949 /* call devpoll() */
950 Py_BEGIN_ALLOW_THREADS
951 errno = 0;
952 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
953 Py_END_ALLOW_THREADS
954
955 if (errno != EINTR)
956 break;
957
958 /* devpoll() was interrupted by a signal */
959 if (PyErr_CheckSignals())
960 return NULL;
961
962 if (timeout >= 0) {
963 timeout = deadline - _PyTime_GetMonotonicClock();
964 if (timeout < 0) {
965 poll_result = 0;
966 break;
967 }
968 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
969 dvp.dp_timeout = (int)ms;
970 /* retry devpoll() with the recomputed timeout */
971 }
972 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100973
974 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300975 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976 return NULL;
977 }
978
979 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100980 result_list = PyList_New(poll_result);
981 if (!result_list)
982 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200983
984 for (i = 0; i < poll_result; i++) {
985 num1 = PyLong_FromLong(self->fds[i].fd);
986 num2 = PyLong_FromLong(self->fds[i].revents);
987 if ((num1 == NULL) || (num2 == NULL)) {
988 Py_XDECREF(num1);
989 Py_XDECREF(num2);
990 goto error;
991 }
992 value = PyTuple_Pack(2, num1, num2);
993 Py_DECREF(num1);
994 Py_DECREF(num2);
995 if (value == NULL)
996 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -0700997 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100998 }
999
1000 return result_list;
1001
1002 error:
1003 Py_DECREF(result_list);
1004 return NULL;
1005}
1006
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001007static int
1008devpoll_internal_close(devpollObject *self)
1009{
1010 int save_errno = 0;
1011 if (self->fd_devpoll >= 0) {
1012 int fd = self->fd_devpoll;
1013 self->fd_devpoll = -1;
1014 Py_BEGIN_ALLOW_THREADS
1015 if (close(fd) < 0)
1016 save_errno = errno;
1017 Py_END_ALLOW_THREADS
1018 }
1019 return save_errno;
1020}
1021
Tal Einat6dc57e22018-06-30 23:02:48 +03001022/*[clinic input]
1023select.devpoll.close
1024
1025Close the devpoll file descriptor.
1026
1027Further operations on the devpoll object will raise an exception.
1028[clinic start generated code]*/
1029
1030static PyObject *
1031select_devpoll_close_impl(devpollObject *self)
1032/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001033{
1034 errno = devpoll_internal_close(self);
1035 if (errno < 0) {
1036 PyErr_SetFromErrno(PyExc_OSError);
1037 return NULL;
1038 }
1039 Py_RETURN_NONE;
1040}
1041
Victor Stinner13423c32013-08-22 00:19:50 +02001042static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001043devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001044{
1045 if (self->fd_devpoll < 0)
1046 Py_RETURN_TRUE;
1047 else
1048 Py_RETURN_FALSE;
1049}
1050
Tal Einat6dc57e22018-06-30 23:02:48 +03001051/*[clinic input]
1052select.devpoll.fileno
1053
1054Return the file descriptor.
1055[clinic start generated code]*/
1056
1057static PyObject *
1058select_devpoll_fileno_impl(devpollObject *self)
1059/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001060{
1061 if (self->fd_devpoll < 0)
1062 return devpoll_err_closed();
1063 return PyLong_FromLong(self->fd_devpoll);
1064}
1065
Victor Stinner13423c32013-08-22 00:19:50 +02001066static PyGetSetDef devpoll_getsetlist[] = {
1067 {"closed", (getter)devpoll_get_closed, NULL,
1068 "True if the devpoll object is closed"},
1069 {0},
1070};
1071
Jesus Cead8b9ae62011-11-14 19:07:41 +01001072static devpollObject *
1073newDevPollObject(void)
1074{
1075 devpollObject *self;
1076 int fd_devpoll, limit_result;
1077 struct pollfd *fds;
1078 struct rlimit limit;
1079
Jesus Cead8b9ae62011-11-14 19:07:41 +01001080 /*
1081 ** If we try to process more that getrlimit()
1082 ** fds, the kernel will give an error, so
1083 ** we set the limit here. It is a dynamic
1084 ** value, because we can change rlimit() anytime.
1085 */
1086 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001087 if (limit_result == -1) {
1088 PyErr_SetFromErrno(PyExc_OSError);
1089 return NULL;
1090 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001091
1092 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1093 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001094 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001095
1096 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1097 if (fds == NULL) {
1098 close(fd_devpoll);
1099 PyErr_NoMemory();
1100 return NULL;
1101 }
1102
Dino Viehlandf9190542019-09-14 15:20:27 +01001103 self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001104 if (self == NULL) {
1105 close(fd_devpoll);
1106 PyMem_DEL(fds);
1107 return NULL;
1108 }
1109 self->fd_devpoll = fd_devpoll;
1110 self->max_n_fds = limit.rlim_cur;
1111 self->n_fds = 0;
1112 self->fds = fds;
1113
1114 return self;
1115}
1116
Dino Viehlandf9190542019-09-14 15:20:27 +01001117static PyObject *
1118devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1119{
1120 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1121 return NULL;
1122}
1123
Jesus Cead8b9ae62011-11-14 19:07:41 +01001124static void
1125devpoll_dealloc(devpollObject *self)
1126{
Dino Viehlandf9190542019-09-14 15:20:27 +01001127 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001128 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001129 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001130 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001131 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001132}
1133
Dino Viehlandf9190542019-09-14 15:20:27 +01001134static PyType_Slot devpoll_Type_slots[] = {
1135 {Py_tp_dealloc, devpoll_dealloc},
1136 {Py_tp_getset, devpoll_getsetlist},
1137 {Py_tp_methods, devpoll_methods},
1138 {Py_tp_new, devpoll_new},
1139 {0, 0},
1140};
1141
1142static PyType_Spec devpoll_Type_spec = {
1143 "select.devpoll",
1144 sizeof(devpollObject),
1145 0,
1146 Py_TPFLAGS_DEFAULT,
1147 devpoll_Type_slots
1148};
1149
Jesus Cead8b9ae62011-11-14 19:07:41 +01001150#endif /* HAVE_SYS_DEVPOLL_H */
1151
1152
Tal Einat6dc57e22018-06-30 23:02:48 +03001153/*[clinic input]
1154select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001155
Tal Einat6dc57e22018-06-30 23:02:48 +03001156Returns a polling object.
1157
1158This object supports registering and unregistering file descriptors, and then
1159polling them for I/O events.
1160[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001161
1162static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001163select_poll_impl(PyObject *module)
1164/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001167}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001168
Jesus Cead8b9ae62011-11-14 19:07:41 +01001169#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001170
1171/*[clinic input]
1172select.devpoll
1173
1174Returns a polling object.
1175
1176This object supports registering and unregistering file descriptors, and then
1177polling them for I/O events.
1178[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001179
1180static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001181select_devpoll_impl(PyObject *module)
1182/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001183{
1184 return (PyObject *)newDevPollObject();
1185}
1186#endif
1187
1188
Thomas Wouters477c8d52006-05-27 19:21:47 +00001189#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001191 * On some systems poll() sets errno on invalid file descriptors. We test
1192 * for this at runtime because this bug may be fixed or introduced between
1193 * OS releases.
1194 */
1195static int select_have_broken_poll(void)
1196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 int poll_test;
1198 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 /* Create a file descriptor to make invalid */
1203 if (pipe(filedes) < 0) {
1204 return 1;
1205 }
1206 poll_struct.fd = filedes[0];
1207 close(filedes[0]);
1208 close(filedes[1]);
1209 poll_test = poll(&poll_struct, 1, 0);
1210 if (poll_test < 0) {
1211 return 1;
1212 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1213 return 1;
1214 }
1215 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001216}
1217#endif /* __APPLE__ */
1218
1219#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001220
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001221#ifdef HAVE_EPOLL
1222/* **************************************************************************
1223 * epoll interface for Linux 2.6
1224 *
1225 * Written by Christian Heimes
1226 * Inspired by Twisted's _epoll.pyx and select.poll()
1227 */
1228
1229#ifdef HAVE_SYS_EPOLL_H
1230#include <sys/epoll.h>
1231#endif
1232
1233typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001235 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001236} pyEpoll_Object;
1237
Dino Viehlandf9190542019-09-14 15:20:27 +01001238#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001239
1240static PyObject *
1241pyepoll_err_closed(void)
1242{
Victor Stinner13423c32013-08-22 00:19:50 +02001243 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001245}
1246
1247static int
1248pyepoll_internal_close(pyEpoll_Object *self)
1249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 int save_errno = 0;
1251 if (self->epfd >= 0) {
1252 int epfd = self->epfd;
1253 self->epfd = -1;
1254 Py_BEGIN_ALLOW_THREADS
1255 if (close(epfd) < 0)
1256 save_errno = errno;
1257 Py_END_ALLOW_THREADS
1258 }
1259 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260}
1261
1262static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001263newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001266 assert(type != NULL);
1267 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1268 assert(epoll_alloc != NULL);
1269 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 if (self == NULL)
1271 return NULL;
1272
1273 if (fd == -1) {
1274 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001275#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001276 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1277#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001278 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001279#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 Py_END_ALLOW_THREADS
1281 }
1282 else {
1283 self->epfd = fd;
1284 }
1285 if (self->epfd < 0) {
1286 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001287 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 return NULL;
1289 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001290
1291#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001292 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001293 Py_DECREF(self);
1294 return NULL;
1295 }
1296#endif
1297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001299}
1300
1301
Tal Einat6dc57e22018-06-30 23:02:48 +03001302/*[clinic input]
1303@classmethod
1304select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001305
Tal Einat6dc57e22018-06-30 23:02:48 +03001306 sizehint: int = -1
1307 The expected number of events to be registered. It must be positive,
1308 or -1 to use the default. It is only used on older systems where
1309 epoll_create1() is not available; otherwise it has no effect (though its
1310 value is still checked).
1311 flags: int = 0
1312 Deprecated and completely ignored. However, when supplied, its value
1313 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1314
1315Returns an epolling object.
1316[clinic start generated code]*/
1317
1318static PyObject *
1319select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1320/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1321{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001322 if (sizehint == -1) {
1323 sizehint = FD_SETSIZE - 1;
1324 }
1325 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001326 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001327 return NULL;
1328 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001329
1330#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001331 if (flags && flags != EPOLL_CLOEXEC) {
1332 PyErr_SetString(PyExc_OSError, "invalid flags");
1333 return NULL;
1334 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001335#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001336
Berker Peksage2197d12016-09-26 23:30:41 +03001337 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001338}
1339
1340
1341static void
1342pyepoll_dealloc(pyEpoll_Object *self)
1343{
Dino Viehlandf9190542019-09-14 15:20:27 +01001344 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001346 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1347 epoll_free((PyObject *)self);
1348 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001349}
1350
Tal Einat6dc57e22018-06-30 23:02:48 +03001351/*[clinic input]
1352select.epoll.close
1353
1354Close the epoll control file descriptor.
1355
1356Further operations on the epoll object will raise an exception.
1357[clinic start generated code]*/
1358
1359static PyObject *
1360select_epoll_close_impl(pyEpoll_Object *self)
1361/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 errno = pyepoll_internal_close(self);
1364 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001365 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 return NULL;
1367 }
1368 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001369}
1370
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001371
1372static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001373pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 if (self->epfd < 0)
1376 Py_RETURN_TRUE;
1377 else
1378 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379}
1380
Tal Einat6dc57e22018-06-30 23:02:48 +03001381/*[clinic input]
1382select.epoll.fileno
1383
1384Return the epoll control file descriptor.
1385[clinic start generated code]*/
1386
1387static PyObject *
1388select_epoll_fileno_impl(pyEpoll_Object *self)
1389/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (self->epfd < 0)
1392 return pyepoll_err_closed();
1393 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001394}
1395
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001396
Tal Einat6dc57e22018-06-30 23:02:48 +03001397/*[clinic input]
1398@classmethod
1399select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001400
Tal Einat6dc57e22018-06-30 23:02:48 +03001401 fd: int
1402 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001403
Tal Einat6dc57e22018-06-30 23:02:48 +03001404Create an epoll object from a given control fd.
1405[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001406
1407static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001408select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1409/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1410{
1411 SOCKET s_fd = (SOCKET)fd;
1412 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1413}
1414
1415
1416static PyObject *
1417pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 struct epoll_event ev;
1420 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 if (epfd < 0)
1423 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001424
Guido van Rossumee07b942013-12-06 17:46:22 -08001425 switch (op) {
1426 case EPOLL_CTL_ADD:
1427 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 ev.events = events;
1429 ev.data.fd = fd;
1430 Py_BEGIN_ALLOW_THREADS
1431 result = epoll_ctl(epfd, op, fd, &ev);
1432 Py_END_ALLOW_THREADS
1433 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001434 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1436 * operation required a non-NULL pointer in event, even
1437 * though this argument is ignored. */
1438 Py_BEGIN_ALLOW_THREADS
1439 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 Py_END_ALLOW_THREADS
1441 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001442 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 result = -1;
1444 errno = EINVAL;
1445 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001448 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 return NULL;
1450 }
1451 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001452}
1453
Tal Einat6dc57e22018-06-30 23:02:48 +03001454/*[clinic input]
1455select.epoll.register
1456
1457 fd: fildes
1458 the target file descriptor of the operation
Anthony Sottiled0518012020-06-23 14:49:56 -07001459 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001460 a bit set composed of the various EPOLL constants
1461
1462Registers a new fd or raises an OSError if the fd is already registered.
1463
1464The epoll interface supports all file descriptors that support poll.
1465[clinic start generated code]*/
1466
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001467static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001468select_epoll_register_impl(pyEpoll_Object *self, int fd,
1469 unsigned int eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -07001470/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471{
Tal Einat6dc57e22018-06-30 23:02:48 +03001472 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001473}
1474
Tal Einat6dc57e22018-06-30 23:02:48 +03001475/*[clinic input]
1476select.epoll.modify
1477
1478 fd: fildes
1479 the target file descriptor of the operation
1480 eventmask: unsigned_int(bitwise=True)
1481 a bit set composed of the various EPOLL constants
1482
1483Modify event mask for a registered file descriptor.
1484[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001485
1486static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001487select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1488 unsigned int eventmask)
1489/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001490{
Tal Einat6dc57e22018-06-30 23:02:48 +03001491 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001492}
1493
Tal Einat6dc57e22018-06-30 23:02:48 +03001494/*[clinic input]
1495select.epoll.unregister
1496
1497 fd: fildes
1498 the target file descriptor of the operation
1499
1500Remove a registered file descriptor from the epoll object.
1501[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502
1503static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001504select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1505/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001506{
Tal Einat6dc57e22018-06-30 23:02:48 +03001507 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001508}
1509
Tal Einat6dc57e22018-06-30 23:02:48 +03001510/*[clinic input]
1511select.epoll.poll
1512
1513 timeout as timeout_obj: object = None
1514 the maximum time to wait in seconds (as float);
1515 a timeout of None or -1 makes poll wait indefinitely
1516 maxevents: int = -1
1517 the maximum number of events returned; -1 means no limit
1518
1519Wait for events on the epoll file descriptor.
1520
1521Returns a list containing any descriptors that have events to report,
1522as a list of (fd, events) 2-tuples.
1523[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001524
1525static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001526select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1527 int maxevents)
1528/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 int nfds, i;
1531 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001532 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001533 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 if (self->epfd < 0)
1536 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001537
Berker Peksagb690b9b2018-09-11 20:29:48 +03001538 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001539 /* epoll_wait() has a resolution of 1 millisecond, round towards
1540 infinity to wait at least timeout seconds. */
1541 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001542 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001543 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1544 PyErr_SetString(PyExc_TypeError,
1545 "timeout must be an integer or None");
1546 }
1547 return NULL;
1548 }
1549
1550 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1551 if (ms < INT_MIN || ms > INT_MAX) {
1552 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1553 return NULL;
1554 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001555 /* epoll_wait(2) treats all arbitrary negative numbers the same
1556 for the timeout argument, but -1 is the documented way to block
1557 indefinitely in the epoll_wait(2) documentation, so we set ms
1558 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001559
Berker Peksagb690b9b2018-09-11 20:29:48 +03001560 Note that we didn't use INFTIM here since it's non-standard and
1561 isn't available under Linux. */
1562 if (ms < 0) {
1563 ms = -1;
1564 }
1565
1566 if (timeout >= 0) {
1567 deadline = _PyTime_GetMonotonicClock() + timeout;
1568 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001572 maxevents = FD_SETSIZE-1;
1573 }
1574 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 PyErr_Format(PyExc_ValueError,
1576 "maxevents must be greater than 0, got %d",
1577 maxevents);
1578 return NULL;
1579 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001580
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001581 evs = PyMem_New(struct epoll_event, maxevents);
1582 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001583 PyErr_NoMemory();
1584 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001586
Victor Stinner41eba222015-03-30 21:59:21 +02001587 do {
1588 Py_BEGIN_ALLOW_THREADS
1589 errno = 0;
1590 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1591 Py_END_ALLOW_THREADS
1592
1593 if (errno != EINTR)
1594 break;
1595
1596 /* poll() was interrupted by a signal */
1597 if (PyErr_CheckSignals())
1598 goto error;
1599
1600 if (timeout >= 0) {
1601 timeout = deadline - _PyTime_GetMonotonicClock();
1602 if (timeout < 0) {
1603 nfds = 0;
1604 break;
1605 }
1606 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1607 /* retry epoll_wait() with the recomputed timeout */
1608 }
1609 } while(1);
1610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001612 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 goto error;
1614 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 elist = PyList_New(nfds);
1617 if (elist == NULL) {
1618 goto error;
1619 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001622 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 if (etuple == NULL) {
1624 Py_CLEAR(elist);
1625 goto error;
1626 }
1627 PyList_SET_ITEM(elist, i, etuple);
1628 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001629
Christian Heimesf6cd9672008-03-26 13:45:42 +00001630 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001631 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001633}
1634
Tal Einat6dc57e22018-06-30 23:02:48 +03001635
1636/*[clinic input]
1637select.epoll.__enter__
1638
1639[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001640
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001641static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001642select_epoll___enter___impl(pyEpoll_Object *self)
1643/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001644{
1645 if (self->epfd < 0)
1646 return pyepoll_err_closed();
1647
1648 Py_INCREF(self);
1649 return (PyObject *)self;
1650}
1651
Tal Einat6dc57e22018-06-30 23:02:48 +03001652/*[clinic input]
1653select.epoll.__exit__
1654
1655 exc_type: object = None
1656 exc_value: object = None
1657 exc_tb: object = None
1658 /
1659
1660[clinic start generated code]*/
1661
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001662static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001663select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1664 PyObject *exc_value, PyObject *exc_tb)
1665/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001666{
Dino Viehlandf9190542019-09-14 15:20:27 +01001667 return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001668}
1669
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001670static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 {"closed", (getter)pyepoll_get_closed, NULL,
1672 "True if the epoll handler is closed"},
1673 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001674};
1675
Dino Viehlandf9190542019-09-14 15:20:27 +01001676PyDoc_STRVAR(pyepoll_doc,
1677"select.epoll(sizehint=-1, flags=0)\n\
1678\n\
1679Returns an epolling object\n\
1680\n\
1681sizehint must be a positive integer or -1 for the default size. The\n\
1682sizehint is used to optimize internal data structures. It doesn't limit\n\
1683the maximum number of monitored events.");
1684
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001685#endif /* HAVE_EPOLL */
1686
1687#ifdef HAVE_KQUEUE
1688/* **************************************************************************
1689 * kqueue interface for BSD
1690 *
1691 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1692 * All rights reserved.
1693 *
1694 * Redistribution and use in source and binary forms, with or without
1695 * modification, are permitted provided that the following conditions
1696 * are met:
1697 * 1. Redistributions of source code must retain the above copyright
1698 * notice, this list of conditions and the following disclaimer.
1699 * 2. Redistributions in binary form must reproduce the above copyright
1700 * notice, this list of conditions and the following disclaimer in the
1701 * documentation and/or other materials provided with the distribution.
1702 *
1703 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1704 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1705 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1706 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1707 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1708 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1709 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1710 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1711 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1712 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1713 * SUCH DAMAGE.
1714 */
1715
1716#ifdef HAVE_SYS_EVENT_H
1717#include <sys/event.h>
1718#endif
1719
1720PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001721"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001722\n\
1723This object is the equivalent of the struct kevent for the C API.\n\
1724\n\
1725See the kqueue manpage for more detailed information about the meaning\n\
1726of the arguments.\n\
1727\n\
1728One minor note: while you might hope that udata could store a\n\
1729reference to a python object, it cannot, because it is impossible to\n\
1730keep a proper reference count of the object once it's passed into the\n\
1731kernel. Therefore, I have restricted it to only storing an integer. I\n\
1732recommend ignoring it and simply using the 'ident' field to key off\n\
1733of. You could also set up a dictionary on the python side to store a\n\
1734udata->object mapping.");
1735
1736typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 PyObject_HEAD
1738 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001739} kqueue_event_Object;
1740
Dino Viehlandf9190542019-09-14 15:20:27 +01001741#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001742
1743typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 PyObject_HEAD
1745 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001746} kqueue_queue_Object;
1747
Dino Viehlandf9190542019-09-14 15:20:27 +01001748#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001749
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 Heimes4fbc72b2008-03-22 00:47:35 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001892 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001894
1895#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1896 result = CMP(s->e.ident, o->e.ident)
1897 : CMP(s->e.filter, o->e.filter)
1898 : CMP(s->e.flags, o->e.flags)
1899 : CMP(s->e.fflags, o->e.fflags)
1900 : CMP(s->e.data, o->e.data)
1901 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1902 : 0;
1903#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001904
stratakise8b19652017-11-02 11:32:54 +01001905 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001906}
1907
Dino Viehlandf9190542019-09-14 15:20:27 +01001908static PyType_Slot kqueue_event_Type_slots[] = {
1909 {Py_tp_doc, (void*)kqueue_event_doc},
1910 {Py_tp_init, kqueue_event_init},
1911 {Py_tp_members, kqueue_event_members},
1912 {Py_tp_new, PyType_GenericNew},
1913 {Py_tp_repr, kqueue_event_repr},
1914 {Py_tp_richcompare, kqueue_event_richcompare},
1915 {0, 0},
1916};
1917
1918static PyType_Spec kqueue_event_Type_spec = {
1919 "select.kevent",
1920 sizeof(kqueue_event_Object),
1921 0,
1922 Py_TPFLAGS_DEFAULT,
1923 kqueue_event_Type_slots
1924};
1925
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001926static PyObject *
1927kqueue_queue_err_closed(void)
1928{
Victor Stinner13423c32013-08-22 00:19:50 +02001929 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001931}
1932
1933static int
1934kqueue_queue_internal_close(kqueue_queue_Object *self)
1935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 int save_errno = 0;
1937 if (self->kqfd >= 0) {
1938 int kqfd = self->kqfd;
1939 self->kqfd = -1;
1940 Py_BEGIN_ALLOW_THREADS
1941 if (close(kqfd) < 0)
1942 save_errno = errno;
1943 Py_END_ALLOW_THREADS
1944 }
1945 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001946}
1947
1948static PyObject *
1949newKqueue_Object(PyTypeObject *type, SOCKET fd)
1950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001952 assert(type != NULL);
1953 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1954 assert(queue_alloc != NULL);
1955 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 if (self == NULL) {
1957 return NULL;
1958 }
1959
1960 if (fd == -1) {
1961 Py_BEGIN_ALLOW_THREADS
1962 self->kqfd = kqueue();
1963 Py_END_ALLOW_THREADS
1964 }
1965 else {
1966 self->kqfd = fd;
1967 }
1968 if (self->kqfd < 0) {
1969 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001970 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 return NULL;
1972 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001973
1974 if (fd == -1) {
1975 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1976 Py_DECREF(self);
1977 return NULL;
1978 }
1979 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001981}
1982
Tal Einat6dc57e22018-06-30 23:02:48 +03001983/*[clinic input]
1984@classmethod
1985select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001986
Tal Einat6dc57e22018-06-30 23:02:48 +03001987Kqueue syscall wrapper.
1988
1989For example, to start watching a socket for input:
1990>>> kq = kqueue()
1991>>> sock = socket()
1992>>> sock.connect((host, port))
1993>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1994
1995To wait one second for it to become writeable:
1996>>> kq.control(None, 1, 1000)
1997
1998To stop listening:
1999>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2000[clinic start generated code]*/
2001
2002static PyObject *
2003select_kqueue_impl(PyTypeObject *type)
2004/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002007}
2008
2009static void
2010kqueue_queue_dealloc(kqueue_queue_Object *self)
2011{
Dino Viehlandf9190542019-09-14 15:20:27 +01002012 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002014 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2015 kqueue_free((PyObject *)self);
2016 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002017}
2018
Tal Einat6dc57e22018-06-30 23:02:48 +03002019/*[clinic input]
2020select.kqueue.close
2021
2022Close the kqueue control file descriptor.
2023
2024Further operations on the kqueue object will raise an exception.
2025[clinic start generated code]*/
2026
2027static PyObject *
2028select_kqueue_close_impl(kqueue_queue_Object *self)
2029/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 errno = kqueue_queue_internal_close(self);
2032 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002033 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 return NULL;
2035 }
2036 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002037}
2038
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002039static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002040kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002041{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 if (self->kqfd < 0)
2043 Py_RETURN_TRUE;
2044 else
2045 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002046}
2047
Tal Einat6dc57e22018-06-30 23:02:48 +03002048/*[clinic input]
2049select.kqueue.fileno
2050
2051Return the kqueue control file descriptor.
2052[clinic start generated code]*/
2053
2054static PyObject *
2055select_kqueue_fileno_impl(kqueue_queue_Object *self)
2056/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 if (self->kqfd < 0)
2059 return kqueue_queue_err_closed();
2060 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002061}
2062
Tal Einat6dc57e22018-06-30 23:02:48 +03002063/*[clinic input]
2064@classmethod
2065select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002066
Tal Einat6dc57e22018-06-30 23:02:48 +03002067 fd: int
2068 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002069
Tal Einat6dc57e22018-06-30 23:02:48 +03002070Create a kqueue object from a given control fd.
2071[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002072
2073static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002074select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2075/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076{
Tal Einat6dc57e22018-06-30 23:02:48 +03002077 SOCKET s_fd = (SOCKET)fd;
2078
2079 return newKqueue_Object(type, s_fd);
2080}
2081
2082/*[clinic input]
2083select.kqueue.control
2084
2085 changelist: object
2086 Must be an iterable of kevent objects describing the changes to be made
2087 to the kernel's watch list or None.
2088 maxevents: int
2089 The maximum number of events that the kernel will return.
2090 timeout as otimeout: object = None
2091 The maximum time to wait in seconds, or else None to wait forever.
2092 This accepts floats for smaller timeouts, too.
2093 /
2094
2095Calls the kernel kevent function.
2096[clinic start generated code]*/
2097
2098static PyObject *
2099select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2100 int maxevents, PyObject *otimeout)
2101/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 int gotevents = 0;
2104 int nchanges = 0;
2105 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002106 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 PyObject *result = NULL;
2108 struct kevent *evl = NULL;
2109 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002110 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002112 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 if (self->kqfd < 0)
2115 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002116
Tal Einat6dc57e22018-06-30 23:02:48 +03002117 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 PyErr_Format(PyExc_ValueError,
2119 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002120 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 return NULL;
2122 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002123
Tal Einat6dc57e22018-06-30 23:02:48 +03002124 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 ptimeoutspec = NULL;
2126 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002127 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002128 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002129 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002130 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002131 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002132 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002133 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002134 return NULL;
2135 }
2136
Victor Stinner4448c082015-03-31 11:48:34 +02002137 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002138 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002139
Victor Stinner4448c082015-03-31 11:48:34 +02002140 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 PyErr_SetString(PyExc_ValueError,
2142 "timeout must be positive or None");
2143 return NULL;
2144 }
Victor Stinner4448c082015-03-31 11:48:34 +02002145 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002147
Tal Einat6dc57e22018-06-30 23:02:48 +03002148 if (changelist != Py_None) {
2149 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002150 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 return NULL;
2152 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002153 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2154 PyErr_SetString(PyExc_OverflowError,
2155 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 goto error;
2157 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002158 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 chl = PyMem_New(struct kevent, nchanges);
2161 if (chl == NULL) {
2162 PyErr_NoMemory();
2163 goto error;
2164 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002165 for (i = 0; i < nchanges; ++i) {
2166 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 PyErr_SetString(PyExc_TypeError,
2169 "changelist must be an iterable of "
2170 "select.kevent objects");
2171 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002173 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002175 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002179 if (maxevents) {
2180 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 if (evl == NULL) {
2182 PyErr_NoMemory();
2183 goto error;
2184 }
2185 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002186
Victor Stinner4448c082015-03-31 11:48:34 +02002187 if (ptimeoutspec)
2188 deadline = _PyTime_GetMonotonicClock() + timeout;
2189
2190 do {
2191 Py_BEGIN_ALLOW_THREADS
2192 errno = 0;
2193 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002194 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002195 Py_END_ALLOW_THREADS
2196
2197 if (errno != EINTR)
2198 break;
2199
2200 /* kevent() was interrupted by a signal */
2201 if (PyErr_CheckSignals())
2202 goto error;
2203
2204 if (ptimeoutspec) {
2205 timeout = deadline - _PyTime_GetMonotonicClock();
2206 if (timeout < 0) {
2207 gotevents = 0;
2208 break;
2209 }
2210 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2211 goto error;
2212 /* retry kevent() with the recomputed timeout */
2213 }
2214 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002216 if (gotevents == -1) {
2217 PyErr_SetFromErrno(PyExc_OSError);
2218 goto error;
2219 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 result = PyList_New(gotevents);
2222 if (result == NULL) {
2223 goto error;
2224 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 for (i = 0; i < gotevents; i++) {
2227 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Dino Viehlandf9190542019-09-14 15:20:27 +01002229 ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 if (ch == NULL) {
2231 goto error;
2232 }
2233 ch->e = evl[i];
2234 PyList_SET_ITEM(result, i, (PyObject *)ch);
2235 }
2236 PyMem_Free(chl);
2237 PyMem_Free(evl);
2238 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002239
2240 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 PyMem_Free(chl);
2242 PyMem_Free(evl);
2243 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002244 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246}
2247
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002248static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 {"closed", (getter)kqueue_queue_get_closed, NULL,
2250 "True if the kqueue handler is closed"},
2251 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002252};
2253
Tal Einat6dc57e22018-06-30 23:02:48 +03002254#endif /* HAVE_KQUEUE */
2255
2256
2257/* ************************************************************************ */
2258
2259#include "clinic/selectmodule.c.h"
2260
2261#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2262
2263static PyMethodDef poll_methods[] = {
2264 SELECT_POLL_REGISTER_METHODDEF
2265 SELECT_POLL_MODIFY_METHODDEF
2266 SELECT_POLL_UNREGISTER_METHODDEF
2267 SELECT_POLL_POLL_METHODDEF
2268 {NULL, NULL} /* sentinel */
2269};
2270
Dino Viehlandf9190542019-09-14 15:20:27 +01002271
2272static PyType_Slot poll_Type_slots[] = {
2273 {Py_tp_dealloc, poll_dealloc},
2274 {Py_tp_methods, poll_methods},
2275 {Py_tp_new, poll_new},
2276 {0, 0},
2277};
2278
2279static PyType_Spec poll_Type_spec = {
2280 "select.poll",
2281 sizeof(pollObject),
2282 0,
2283 Py_TPFLAGS_DEFAULT,
2284 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002285};
2286
2287#ifdef HAVE_SYS_DEVPOLL_H
2288
2289static PyMethodDef devpoll_methods[] = {
2290 SELECT_DEVPOLL_REGISTER_METHODDEF
2291 SELECT_DEVPOLL_MODIFY_METHODDEF
2292 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2293 SELECT_DEVPOLL_POLL_METHODDEF
2294 SELECT_DEVPOLL_CLOSE_METHODDEF
2295 SELECT_DEVPOLL_FILENO_METHODDEF
2296 {NULL, NULL} /* sentinel */
2297};
2298
Tal Einat6dc57e22018-06-30 23:02:48 +03002299#endif /* HAVE_SYS_DEVPOLL_H */
2300
2301#endif /* HAVE_POLL */
2302
2303#ifdef HAVE_EPOLL
2304
2305static PyMethodDef pyepoll_methods[] = {
2306 SELECT_EPOLL_FROMFD_METHODDEF
2307 SELECT_EPOLL_CLOSE_METHODDEF
2308 SELECT_EPOLL_FILENO_METHODDEF
2309 SELECT_EPOLL_MODIFY_METHODDEF
2310 SELECT_EPOLL_REGISTER_METHODDEF
2311 SELECT_EPOLL_UNREGISTER_METHODDEF
2312 SELECT_EPOLL_POLL_METHODDEF
2313 SELECT_EPOLL___ENTER___METHODDEF
2314 SELECT_EPOLL___EXIT___METHODDEF
2315 {NULL, NULL},
2316};
2317
Dino Viehlandf9190542019-09-14 15:20:27 +01002318static PyType_Slot pyEpoll_Type_slots[] = {
2319 {Py_tp_dealloc, pyepoll_dealloc},
2320 {Py_tp_doc, (void*)pyepoll_doc},
2321 {Py_tp_getattro, PyObject_GenericGetAttr},
2322 {Py_tp_getset, pyepoll_getsetlist},
2323 {Py_tp_methods, pyepoll_methods},
2324 {Py_tp_new, select_epoll},
2325 {0, 0},
2326};
2327
2328static PyType_Spec pyEpoll_Type_spec = {
2329 "select.epoll",
2330 sizeof(pyEpoll_Object),
2331 0,
2332 Py_TPFLAGS_DEFAULT,
2333 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002334};
2335
2336#endif /* HAVE_EPOLL */
2337
2338#ifdef HAVE_KQUEUE
2339
Tal Einat6dc57e22018-06-30 23:02:48 +03002340static PyMethodDef kqueue_queue_methods[] = {
2341 SELECT_KQUEUE_FROMFD_METHODDEF
2342 SELECT_KQUEUE_CLOSE_METHODDEF
2343 SELECT_KQUEUE_FILENO_METHODDEF
2344 SELECT_KQUEUE_CONTROL_METHODDEF
2345 {NULL, NULL},
2346};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002347
Dino Viehlandf9190542019-09-14 15:20:27 +01002348static PyType_Slot kqueue_queue_Type_slots[] = {
2349 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002350 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002351 {Py_tp_getset, kqueue_queue_getsetlist},
2352 {Py_tp_methods, kqueue_queue_methods},
2353 {Py_tp_new, select_kqueue},
2354 {0, 0},
2355};
2356
2357static PyType_Spec kqueue_queue_Type_spec = {
2358 "select.kqueue",
2359 sizeof(kqueue_queue_Object),
2360 0,
2361 Py_TPFLAGS_DEFAULT,
2362 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002363};
2364
2365#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002366
2367
2368
2369
2370
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002371/* ************************************************************************ */
2372
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002373
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002374static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002375 SELECT_SELECT_METHODDEF
2376 SELECT_POLL_METHODDEF
2377 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002379};
2380
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002381PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002382"This module supports asynchronous I/O on multiple file descriptors.\n\
2383\n\
2384*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002385On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002386
Martin v. Löwis1a214512008-06-11 05:26:20 +00002387
Dino Viehlandf9190542019-09-14 15:20:27 +01002388
2389static int
2390_select_traverse(PyObject *module, visitproc visit, void *arg)
2391{
Hai Shif707d942020-03-16 21:15:01 +08002392 Py_VISIT(get_select_state(module)->close);
2393 Py_VISIT(get_select_state(module)->poll_Type);
2394 Py_VISIT(get_select_state(module)->devpoll_Type);
2395 Py_VISIT(get_select_state(module)->pyEpoll_Type);
2396 Py_VISIT(get_select_state(module)->kqueue_event_Type);
2397 Py_VISIT(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002398 return 0;
2399}
2400
2401static int
2402_select_clear(PyObject *module)
2403{
Hai Shif707d942020-03-16 21:15:01 +08002404 Py_CLEAR(get_select_state(module)->close);
2405 Py_CLEAR(get_select_state(module)->poll_Type);
2406 Py_CLEAR(get_select_state(module)->devpoll_Type);
2407 Py_CLEAR(get_select_state(module)->pyEpoll_Type);
2408 Py_CLEAR(get_select_state(module)->kqueue_event_Type);
2409 Py_CLEAR(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002410 return 0;
2411}
2412
2413static void
2414_select_free(void *module)
2415{
2416 _select_clear((PyObject *)module);
2417}
2418
Martin v. Löwis1a214512008-06-11 05:26:20 +00002419static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 PyModuleDef_HEAD_INIT,
2421 "select",
2422 module_doc,
Dino Viehlandf9190542019-09-14 15:20:27 +01002423 sizeof(_selectstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 select_methods,
2425 NULL,
Dino Viehlandf9190542019-09-14 15:20:27 +01002426 _select_traverse,
2427 _select_clear,
2428 _select_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002429};
2430
Mark Hammond62b1ab12002-07-23 06:31:15 +00002431PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002432PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002433{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 PyObject *m;
2435 m = PyModule_Create(&selectmodule);
2436 if (m == NULL)
2437 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002438
Hai Shif707d942020-03-16 21:15:01 +08002439 get_select_state(m)->close = PyUnicode_InternFromString("close");
Dino Viehlandf9190542019-09-14 15:20:27 +01002440
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002441 Py_INCREF(PyExc_OSError);
2442 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002443
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002444#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002445#ifdef HAVE_BROKEN_PIPE_BUF
2446#undef PIPE_BUF
2447#define PIPE_BUF 512
2448#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002449 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002450#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002451
Charles-François Natali986a56c2013-01-19 12:19:10 +01002452#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002453#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 if (select_have_broken_poll()) {
2455 if (PyObject_DelAttrString(m, "poll") == -1) {
2456 PyErr_Clear();
2457 }
2458 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002459#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002461#endif
Dino Viehlandf9190542019-09-14 15:20:27 +01002462 PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
2463 if (poll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002465 get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002466
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002467 PyModule_AddIntMacro(m, POLLIN);
2468 PyModule_AddIntMacro(m, POLLPRI);
2469 PyModule_AddIntMacro(m, POLLOUT);
2470 PyModule_AddIntMacro(m, POLLERR);
2471 PyModule_AddIntMacro(m, POLLHUP);
2472 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002473
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002474#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002475 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002476#endif
2477#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002478 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002479#endif
2480#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002481 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002482#endif
2483#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002484 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002485#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002486#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002487 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002488#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002489#ifdef POLLRDHUP
2490 /* Kernel 2.6.17+ */
2491 PyModule_AddIntMacro(m, POLLRDHUP);
2492#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002494#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002495
Jesus Cead8b9ae62011-11-14 19:07:41 +01002496#ifdef HAVE_SYS_DEVPOLL_H
Dino Viehlandf9190542019-09-14 15:20:27 +01002497 PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
2498 if (devpoll_Type == NULL)
Jesus Cead8b9ae62011-11-14 19:07:41 +01002499 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002500 get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
Jesus Cead8b9ae62011-11-14 19:07:41 +01002501#endif
2502
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002503#ifdef HAVE_EPOLL
Dino Viehlandf9190542019-09-14 15:20:27 +01002504 PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
2505 if (pyEpoll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002507 get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002508 Py_INCREF(pyEpoll_Type);
Hai Shif707d942020-03-16 21:15:01 +08002509 PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002510
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002511 PyModule_AddIntMacro(m, EPOLLIN);
2512 PyModule_AddIntMacro(m, EPOLLOUT);
2513 PyModule_AddIntMacro(m, EPOLLPRI);
2514 PyModule_AddIntMacro(m, EPOLLERR);
2515 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002516#ifdef EPOLLRDHUP
2517 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002518 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002519#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002520 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002521#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002523 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002524#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002525#ifdef EPOLLEXCLUSIVE
2526 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2527#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002528
2529#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002530 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002531#endif
2532#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002533 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002534#endif
2535#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002536 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002537#endif
2538#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002539 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002540#endif
2541#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002542 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002543#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002544
Benjamin Peterson95c16622011-12-27 15:36:32 -06002545#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002546 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002547#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002548#endif /* HAVE_EPOLL */
2549
2550#ifdef HAVE_KQUEUE
Dino Viehlandf9190542019-09-14 15:20:27 +01002551 PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
2552 if (kqueue_event_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002553 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002554 get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
2555 Py_INCREF(get_select_state(m)->kqueue_event_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002556 PyModule_AddObject(m, "kevent", kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002557
Dino Viehlandf9190542019-09-14 15:20:27 +01002558 PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
2559 if (kqueue_queue_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002561 get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
2562 Py_INCREF(get_select_state(m)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002563 PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564
2565 /* event filters */
2566 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2567 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002568#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002570#endif
2571#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
2574#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002577#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002579#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002580#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002582#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585 /* event flags */
2586 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2587 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2588 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2589 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2590 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2591 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002592
Berker Peksag7ec64562016-09-14 18:16:59 +03002593#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002595#endif
2596#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2601 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002603 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002604#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002606#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002609#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002610 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2611 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2612 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2613 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2615 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2616 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002617#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2622 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2623 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2624 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2625 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2628 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2629 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002630#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631
2632 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002633#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2635 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2636 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002637#endif
2638
2639#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002641}