blob: d02e3905f57e5fc19c7bd8abf0b13a4737b36eaf [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 Storchakab510e102020-10-26 12:47:57 +0200502 err = PyDict_Contains(self->dict, key);
503 if (err < 0) {
504 Py_DECREF(key);
505 return NULL;
506 }
507 if (err == 0) {
508 errno = ENOENT;
509 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200510 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return NULL;
512 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300513 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 if (value == NULL) {
515 Py_DECREF(key);
516 return NULL;
517 }
518 err = PyDict_SetItem(self->dict, key, value);
519 Py_DECREF(key);
520 Py_DECREF(value);
521 if (err < 0)
522 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 self->ufd_uptodate = 0;
525
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200526 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000527}
528
529
Tal Einat6dc57e22018-06-30 23:02:48 +0300530/*[clinic input]
531select.poll.unregister
532
533 fd: fildes
534 /
535
536Remove a file descriptor being tracked by the polling object.
537[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000538
539static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300540select_poll_unregister_impl(pollObject *self, int fd)
541/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 /* Check whether the fd is already in the array */
546 key = PyLong_FromLong(fd);
547 if (key == NULL)
548 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 if (PyDict_DelItem(self->dict, key) == -1) {
551 Py_DECREF(key);
552 /* This will simply raise the KeyError set by PyDict_DelItem
553 if the file descriptor isn't registered. */
554 return NULL;
555 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 Py_DECREF(key);
558 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000559
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200560 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000561}
562
Tal Einat6dc57e22018-06-30 23:02:48 +0300563/*[clinic input]
564select.poll.poll
565
566 timeout as timeout_obj: object = None
567 /
568
569Polls the set of registered file descriptors.
570
571Returns a list containing any descriptors that have events or errors to
572report, as a list of (fd, event) 2-tuples.
573[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000574
575static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300576select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
577/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000578{
Tal Einat6dc57e22018-06-30 23:02:48 +0300579 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200580 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200582 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200583 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000584
Tal Einat6dc57e22018-06-30 23:02:48 +0300585 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200586 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100587 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200588 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
589 PyErr_SetString(PyExc_TypeError,
590 "timeout must be an integer or None");
591 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200593 }
594
Pablo Galindo2c15b292017-10-17 15:14:41 +0100595 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200596 if (ms < INT_MIN || ms > INT_MAX) {
597 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200599 }
600
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200601 if (timeout >= 0) {
602 deadline = _PyTime_GetMonotonicClock() + timeout;
603 }
604 }
605
606 /* On some OSes, typically BSD-based ones, the timeout parameter of the
607 poll() syscall, when negative, must be exactly INFTIM, where defined,
608 or -1. See issue 31334. */
609 if (ms < 0) {
610#ifdef INFTIM
611 ms = INFTIM;
612#else
613 ms = -1;
614#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000616
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300617 /* Avoid concurrent poll() invocation, issue 8865 */
618 if (self->poll_running) {
619 PyErr_SetString(PyExc_RuntimeError,
620 "concurrent poll() invocation");
621 return NULL;
622 }
623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 /* Ensure the ufd array is up to date */
625 if (!self->ufd_uptodate)
626 if (update_ufd_array(self) == 0)
627 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300629 self->poll_running = 1;
630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200632 async_err = 0;
633 do {
634 Py_BEGIN_ALLOW_THREADS
635 errno = 0;
636 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
637 Py_END_ALLOW_THREADS
638
639 if (errno != EINTR)
640 break;
641
642 /* poll() was interrupted by a signal */
643 if (PyErr_CheckSignals()) {
644 async_err = 1;
645 break;
646 }
647
648 if (timeout >= 0) {
649 timeout = deadline - _PyTime_GetMonotonicClock();
650 if (timeout < 0) {
651 poll_result = 0;
652 break;
653 }
654 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
655 /* retry poll() with the recomputed timeout */
656 }
657 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300659 self->poll_running = 0;
660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200662 if (!async_err)
663 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 return NULL;
665 }
666
667 /* build the result list */
668
669 result_list = PyList_New(poll_result);
670 if (!result_list)
671 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200673 for (i = 0, j = 0; j < poll_result; j++) {
674 /* skip to the next fired descriptor */
675 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 i++;
677 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200678 /* if we hit a NULL return, set value to NULL
679 and break out of loop; code at end will
680 clean up result_list */
681 value = PyTuple_New(2);
682 if (value == NULL)
683 goto error;
684 num = PyLong_FromLong(self->ufds[i].fd);
685 if (num == NULL) {
686 Py_DECREF(value);
687 goto error;
688 }
689 PyTuple_SET_ITEM(value, 0, num);
690
691 /* The &0xffff is a workaround for AIX. 'revents'
692 is a 16-bit short, and IBM assigned POLLNVAL
693 to be 0x8000, so the conversion to int results
694 in a negative number. See SF bug #923315. */
695 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
696 if (num == NULL) {
697 Py_DECREF(value);
698 goto error;
699 }
700 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700701 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200702 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000703 }
704 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000705
706 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 Py_DECREF(result_list);
708 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000709}
710
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000711static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000712newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 pollObject *self;
Dino Viehlandf9190542019-09-14 15:20:27 +0100715 self = PyObject_New(pollObject, _selectstate_global->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 if (self == NULL)
717 return NULL;
718 /* ufd_uptodate is a Boolean, denoting whether the
719 array pointed to by ufds matches the contents of the dictionary. */
720 self->ufd_uptodate = 0;
721 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300722 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 self->dict = PyDict_New();
724 if (self->dict == NULL) {
725 Py_DECREF(self);
726 return NULL;
727 }
728 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000729}
730
Dino Viehlandf9190542019-09-14 15:20:27 +0100731static PyObject *
732poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
733{
734 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
735 return NULL;
736}
737
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000738static void
739poll_dealloc(pollObject *self)
740{
Dino Viehlandf9190542019-09-14 15:20:27 +0100741 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 if (self->ufds != NULL)
743 PyMem_DEL(self->ufds);
744 Py_XDECREF(self->dict);
745 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100746 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000747}
748
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000749
Jesus Cead8b9ae62011-11-14 19:07:41 +0100750#ifdef HAVE_SYS_DEVPOLL_H
Batuhan Taskaya31245d12020-05-17 01:36:14 +0300751static PyMethodDef devpoll_methods[];
752
Jesus Cead8b9ae62011-11-14 19:07:41 +0100753typedef struct {
754 PyObject_HEAD
755 int fd_devpoll;
756 int max_n_fds;
757 int n_fds;
758 struct pollfd *fds;
759} devpollObject;
760
Victor Stinner13423c32013-08-22 00:19:50 +0200761static PyObject *
762devpoll_err_closed(void)
763{
764 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
765 return NULL;
766}
767
Jesus Cead8b9ae62011-11-14 19:07:41 +0100768static int devpoll_flush(devpollObject *self)
769{
770 int size, n;
771
772 if (!self->n_fds) return 0;
773
774 size = sizeof(struct pollfd)*self->n_fds;
775 self->n_fds = 0;
776
Victor Stinner54799672015-03-19 23:33:09 +0100777 n = _Py_write(self->fd_devpoll, self->fds, size);
778 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100779 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100780
Jesus Cead8b9ae62011-11-14 19:07:41 +0100781 if (n < size) {
782 /*
783 ** Data writed to /dev/poll is a binary data structure. It is not
784 ** clear what to do if a partial write occurred. For now, raise
785 ** an exception and see if we actually found this problem in
786 ** the wild.
787 ** See http://bugs.python.org/issue6397.
788 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300789 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100790 "Please, report at http://bugs.python.org/. "
791 "Data to report: Size tried: %d, actual size written: %d.",
792 size, n);
793 return -1;
794 }
795 return 0;
796}
797
798static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300799internal_devpoll_register(devpollObject *self, int fd,
800 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100801{
Victor Stinner13423c32013-08-22 00:19:50 +0200802 if (self->fd_devpoll < 0)
803 return devpoll_err_closed();
804
Jesus Cead8b9ae62011-11-14 19:07:41 +0100805 if (remove) {
806 self->fds[self->n_fds].fd = fd;
807 self->fds[self->n_fds].events = POLLREMOVE;
808
809 if (++self->n_fds == self->max_n_fds) {
810 if (devpoll_flush(self))
811 return NULL;
812 }
813 }
814
815 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200816 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100817
818 if (++self->n_fds == self->max_n_fds) {
819 if (devpoll_flush(self))
820 return NULL;
821 }
822
823 Py_RETURN_NONE;
824}
825
Tal Einat6dc57e22018-06-30 23:02:48 +0300826/*[clinic input]
827select.devpoll.register
828
829 fd: fildes
830 either an integer, or an object with a fileno() method returning
831 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700832 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300833 an optional bitmask describing the type of events to check for
834 /
835
836Register a file descriptor with the polling object.
837[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100838
839static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300840select_devpoll_register_impl(devpollObject *self, int fd,
841 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700842/*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100843{
Tal Einat6dc57e22018-06-30 23:02:48 +0300844 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100845}
846
Tal Einat6dc57e22018-06-30 23:02:48 +0300847/*[clinic input]
848select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100849
Tal Einat6dc57e22018-06-30 23:02:48 +0300850 fd: fildes
851 either an integer, or an object with a fileno() method returning
852 an int
Anthony Sottiled0518012020-06-23 14:49:56 -0700853 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300854 an optional bitmask describing the type of events to check for
855 /
856
857Modify a possible already registered file descriptor.
858[clinic start generated code]*/
859
860static PyObject *
861select_devpoll_modify_impl(devpollObject *self, int fd,
862 unsigned short eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -0700863/*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100864{
Tal Einat6dc57e22018-06-30 23:02:48 +0300865 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100866}
867
Tal Einat6dc57e22018-06-30 23:02:48 +0300868/*[clinic input]
869select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100870
Tal Einat6dc57e22018-06-30 23:02:48 +0300871 fd: fildes
872 /
873
874Remove a file descriptor being tracked by the polling object.
875[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100876
877static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300878select_devpoll_unregister_impl(devpollObject *self, int fd)
879/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100880{
Victor Stinner13423c32013-08-22 00:19:50 +0200881 if (self->fd_devpoll < 0)
882 return devpoll_err_closed();
883
Jesus Cead8b9ae62011-11-14 19:07:41 +0100884 self->fds[self->n_fds].fd = fd;
885 self->fds[self->n_fds].events = POLLREMOVE;
886
887 if (++self->n_fds == self->max_n_fds) {
888 if (devpoll_flush(self))
889 return NULL;
890 }
891
892 Py_RETURN_NONE;
893}
894
Tal Einat6dc57e22018-06-30 23:02:48 +0300895/*[clinic input]
896select.devpoll.poll
897 timeout as timeout_obj: object = None
898 /
899
900Polls the set of registered file descriptors.
901
902Returns a list containing any descriptors that have events or errors to
903report, as a list of (fd, event) 2-tuples.
904[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100905
906static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300907select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
908/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909{
910 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200911 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100913 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200914 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100915
Victor Stinner13423c32013-08-22 00:19:50 +0200916 if (self->fd_devpoll < 0)
917 return devpoll_err_closed();
918
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300920 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100921 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200922 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100923 }
924 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200925 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100926 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200927 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
928 PyErr_SetString(PyExc_TypeError,
929 "timeout must be an integer or None");
930 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100931 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100933
Pablo Galindo2c15b292017-10-17 15:14:41 +0100934 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200935 if (ms < -1 || ms > INT_MAX) {
936 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
937 return NULL;
938 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100939 }
940
941 if (devpoll_flush(self))
942 return NULL;
943
944 dvp.dp_fds = self->fds;
945 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200946 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100947
Victor Stinner45ca48b2015-03-31 12:10:33 +0200948 if (timeout >= 0)
949 deadline = _PyTime_GetMonotonicClock() + timeout;
950
951 do {
952 /* call devpoll() */
953 Py_BEGIN_ALLOW_THREADS
954 errno = 0;
955 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
956 Py_END_ALLOW_THREADS
957
958 if (errno != EINTR)
959 break;
960
961 /* devpoll() was interrupted by a signal */
962 if (PyErr_CheckSignals())
963 return NULL;
964
965 if (timeout >= 0) {
966 timeout = deadline - _PyTime_GetMonotonicClock();
967 if (timeout < 0) {
968 poll_result = 0;
969 break;
970 }
971 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
972 dvp.dp_timeout = (int)ms;
973 /* retry devpoll() with the recomputed timeout */
974 }
975 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976
977 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300978 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100979 return NULL;
980 }
981
982 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100983 result_list = PyList_New(poll_result);
984 if (!result_list)
985 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200986
987 for (i = 0; i < poll_result; i++) {
988 num1 = PyLong_FromLong(self->fds[i].fd);
989 num2 = PyLong_FromLong(self->fds[i].revents);
990 if ((num1 == NULL) || (num2 == NULL)) {
991 Py_XDECREF(num1);
992 Py_XDECREF(num2);
993 goto error;
994 }
995 value = PyTuple_Pack(2, num1, num2);
996 Py_DECREF(num1);
997 Py_DECREF(num2);
998 if (value == NULL)
999 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001000 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001001 }
1002
1003 return result_list;
1004
1005 error:
1006 Py_DECREF(result_list);
1007 return NULL;
1008}
1009
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001010static int
1011devpoll_internal_close(devpollObject *self)
1012{
1013 int save_errno = 0;
1014 if (self->fd_devpoll >= 0) {
1015 int fd = self->fd_devpoll;
1016 self->fd_devpoll = -1;
1017 Py_BEGIN_ALLOW_THREADS
1018 if (close(fd) < 0)
1019 save_errno = errno;
1020 Py_END_ALLOW_THREADS
1021 }
1022 return save_errno;
1023}
1024
Tal Einat6dc57e22018-06-30 23:02:48 +03001025/*[clinic input]
1026select.devpoll.close
1027
1028Close the devpoll file descriptor.
1029
1030Further operations on the devpoll object will raise an exception.
1031[clinic start generated code]*/
1032
1033static PyObject *
1034select_devpoll_close_impl(devpollObject *self)
1035/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001036{
1037 errno = devpoll_internal_close(self);
1038 if (errno < 0) {
1039 PyErr_SetFromErrno(PyExc_OSError);
1040 return NULL;
1041 }
1042 Py_RETURN_NONE;
1043}
1044
Victor Stinner13423c32013-08-22 00:19:50 +02001045static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001046devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001047{
1048 if (self->fd_devpoll < 0)
1049 Py_RETURN_TRUE;
1050 else
1051 Py_RETURN_FALSE;
1052}
1053
Tal Einat6dc57e22018-06-30 23:02:48 +03001054/*[clinic input]
1055select.devpoll.fileno
1056
1057Return the file descriptor.
1058[clinic start generated code]*/
1059
1060static PyObject *
1061select_devpoll_fileno_impl(devpollObject *self)
1062/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001063{
1064 if (self->fd_devpoll < 0)
1065 return devpoll_err_closed();
1066 return PyLong_FromLong(self->fd_devpoll);
1067}
1068
Victor Stinner13423c32013-08-22 00:19:50 +02001069static PyGetSetDef devpoll_getsetlist[] = {
1070 {"closed", (getter)devpoll_get_closed, NULL,
1071 "True if the devpoll object is closed"},
1072 {0},
1073};
1074
Jesus Cead8b9ae62011-11-14 19:07:41 +01001075static devpollObject *
1076newDevPollObject(void)
1077{
1078 devpollObject *self;
1079 int fd_devpoll, limit_result;
1080 struct pollfd *fds;
1081 struct rlimit limit;
1082
Jesus Cead8b9ae62011-11-14 19:07:41 +01001083 /*
1084 ** If we try to process more that getrlimit()
1085 ** fds, the kernel will give an error, so
1086 ** we set the limit here. It is a dynamic
1087 ** value, because we can change rlimit() anytime.
1088 */
1089 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090 if (limit_result == -1) {
1091 PyErr_SetFromErrno(PyExc_OSError);
1092 return NULL;
1093 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001094
1095 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1096 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001097 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001098
1099 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1100 if (fds == NULL) {
1101 close(fd_devpoll);
1102 PyErr_NoMemory();
1103 return NULL;
1104 }
1105
Dino Viehlandf9190542019-09-14 15:20:27 +01001106 self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001107 if (self == NULL) {
1108 close(fd_devpoll);
1109 PyMem_DEL(fds);
1110 return NULL;
1111 }
1112 self->fd_devpoll = fd_devpoll;
1113 self->max_n_fds = limit.rlim_cur;
1114 self->n_fds = 0;
1115 self->fds = fds;
1116
1117 return self;
1118}
1119
Dino Viehlandf9190542019-09-14 15:20:27 +01001120static PyObject *
1121devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1122{
1123 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1124 return NULL;
1125}
1126
Jesus Cead8b9ae62011-11-14 19:07:41 +01001127static void
1128devpoll_dealloc(devpollObject *self)
1129{
Dino Viehlandf9190542019-09-14 15:20:27 +01001130 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001131 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001132 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001133 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001134 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001135}
1136
Dino Viehlandf9190542019-09-14 15:20:27 +01001137static PyType_Slot devpoll_Type_slots[] = {
1138 {Py_tp_dealloc, devpoll_dealloc},
1139 {Py_tp_getset, devpoll_getsetlist},
1140 {Py_tp_methods, devpoll_methods},
1141 {Py_tp_new, devpoll_new},
1142 {0, 0},
1143};
1144
1145static PyType_Spec devpoll_Type_spec = {
1146 "select.devpoll",
1147 sizeof(devpollObject),
1148 0,
1149 Py_TPFLAGS_DEFAULT,
1150 devpoll_Type_slots
1151};
1152
Jesus Cead8b9ae62011-11-14 19:07:41 +01001153#endif /* HAVE_SYS_DEVPOLL_H */
1154
1155
Tal Einat6dc57e22018-06-30 23:02:48 +03001156/*[clinic input]
1157select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001158
Tal Einat6dc57e22018-06-30 23:02:48 +03001159Returns a polling object.
1160
1161This object supports registering and unregistering file descriptors, and then
1162polling them for I/O events.
1163[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001164
1165static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001166select_poll_impl(PyObject *module)
1167/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001170}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171
Jesus Cead8b9ae62011-11-14 19:07:41 +01001172#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001173
1174/*[clinic input]
1175select.devpoll
1176
1177Returns a polling object.
1178
1179This object supports registering and unregistering file descriptors, and then
1180polling them for I/O events.
1181[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001182
1183static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001184select_devpoll_impl(PyObject *module)
1185/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001186{
1187 return (PyObject *)newDevPollObject();
1188}
1189#endif
1190
1191
Thomas Wouters477c8d52006-05-27 19:21:47 +00001192#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194 * On some systems poll() sets errno on invalid file descriptors. We test
1195 * for this at runtime because this bug may be fixed or introduced between
1196 * OS releases.
1197 */
1198static int select_have_broken_poll(void)
1199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 int poll_test;
1201 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 /* Create a file descriptor to make invalid */
1206 if (pipe(filedes) < 0) {
1207 return 1;
1208 }
1209 poll_struct.fd = filedes[0];
1210 close(filedes[0]);
1211 close(filedes[1]);
1212 poll_test = poll(&poll_struct, 1, 0);
1213 if (poll_test < 0) {
1214 return 1;
1215 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1216 return 1;
1217 }
1218 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001219}
1220#endif /* __APPLE__ */
1221
1222#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001223
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001224#ifdef HAVE_EPOLL
1225/* **************************************************************************
1226 * epoll interface for Linux 2.6
1227 *
1228 * Written by Christian Heimes
1229 * Inspired by Twisted's _epoll.pyx and select.poll()
1230 */
1231
1232#ifdef HAVE_SYS_EPOLL_H
1233#include <sys/epoll.h>
1234#endif
1235
1236typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001238 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001239} pyEpoll_Object;
1240
Dino Viehlandf9190542019-09-14 15:20:27 +01001241#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001242
1243static PyObject *
1244pyepoll_err_closed(void)
1245{
Victor Stinner13423c32013-08-22 00:19:50 +02001246 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248}
1249
1250static int
1251pyepoll_internal_close(pyEpoll_Object *self)
1252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 int save_errno = 0;
1254 if (self->epfd >= 0) {
1255 int epfd = self->epfd;
1256 self->epfd = -1;
1257 Py_BEGIN_ALLOW_THREADS
1258 if (close(epfd) < 0)
1259 save_errno = errno;
1260 Py_END_ALLOW_THREADS
1261 }
1262 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001263}
1264
1265static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001266newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001269 assert(type != NULL);
1270 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1271 assert(epoll_alloc != NULL);
1272 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 if (self == NULL)
1274 return NULL;
1275
1276 if (fd == -1) {
1277 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001278#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001279 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1280#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001281 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001282#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 Py_END_ALLOW_THREADS
1284 }
1285 else {
1286 self->epfd = fd;
1287 }
1288 if (self->epfd < 0) {
1289 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001290 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 return NULL;
1292 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001293
1294#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001295 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001296 Py_DECREF(self);
1297 return NULL;
1298 }
1299#endif
1300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001302}
1303
1304
Tal Einat6dc57e22018-06-30 23:02:48 +03001305/*[clinic input]
1306@classmethod
1307select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001308
Tal Einat6dc57e22018-06-30 23:02:48 +03001309 sizehint: int = -1
1310 The expected number of events to be registered. It must be positive,
1311 or -1 to use the default. It is only used on older systems where
1312 epoll_create1() is not available; otherwise it has no effect (though its
1313 value is still checked).
1314 flags: int = 0
1315 Deprecated and completely ignored. However, when supplied, its value
1316 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1317
1318Returns an epolling object.
1319[clinic start generated code]*/
1320
1321static PyObject *
1322select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1323/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1324{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001325 if (sizehint == -1) {
1326 sizehint = FD_SETSIZE - 1;
1327 }
1328 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001329 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001330 return NULL;
1331 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001332
1333#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001334 if (flags && flags != EPOLL_CLOEXEC) {
1335 PyErr_SetString(PyExc_OSError, "invalid flags");
1336 return NULL;
1337 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001338#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001339
Berker Peksage2197d12016-09-26 23:30:41 +03001340 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001341}
1342
1343
1344static void
1345pyepoll_dealloc(pyEpoll_Object *self)
1346{
Dino Viehlandf9190542019-09-14 15:20:27 +01001347 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001349 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1350 epoll_free((PyObject *)self);
1351 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001352}
1353
Tal Einat6dc57e22018-06-30 23:02:48 +03001354/*[clinic input]
1355select.epoll.close
1356
1357Close the epoll control file descriptor.
1358
1359Further operations on the epoll object will raise an exception.
1360[clinic start generated code]*/
1361
1362static PyObject *
1363select_epoll_close_impl(pyEpoll_Object *self)
1364/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 errno = pyepoll_internal_close(self);
1367 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001368 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 return NULL;
1370 }
1371 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372}
1373
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001374
1375static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001376pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 if (self->epfd < 0)
1379 Py_RETURN_TRUE;
1380 else
1381 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001382}
1383
Tal Einat6dc57e22018-06-30 23:02:48 +03001384/*[clinic input]
1385select.epoll.fileno
1386
1387Return the epoll control file descriptor.
1388[clinic start generated code]*/
1389
1390static PyObject *
1391select_epoll_fileno_impl(pyEpoll_Object *self)
1392/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 if (self->epfd < 0)
1395 return pyepoll_err_closed();
1396 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001397}
1398
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001399
Tal Einat6dc57e22018-06-30 23:02:48 +03001400/*[clinic input]
1401@classmethod
1402select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001403
Tal Einat6dc57e22018-06-30 23:02:48 +03001404 fd: int
1405 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001406
Tal Einat6dc57e22018-06-30 23:02:48 +03001407Create an epoll object from a given control fd.
1408[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001409
1410static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001411select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1412/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1413{
1414 SOCKET s_fd = (SOCKET)fd;
1415 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1416}
1417
1418
1419static PyObject *
1420pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 struct epoll_event ev;
1423 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if (epfd < 0)
1426 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001427
Guido van Rossumee07b942013-12-06 17:46:22 -08001428 switch (op) {
1429 case EPOLL_CTL_ADD:
1430 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 ev.events = events;
1432 ev.data.fd = fd;
1433 Py_BEGIN_ALLOW_THREADS
1434 result = epoll_ctl(epfd, op, fd, &ev);
1435 Py_END_ALLOW_THREADS
1436 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001437 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1439 * operation required a non-NULL pointer in event, even
1440 * though this argument is ignored. */
1441 Py_BEGIN_ALLOW_THREADS
1442 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 Py_END_ALLOW_THREADS
1444 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001445 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 result = -1;
1447 errno = EINVAL;
1448 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001451 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 return NULL;
1453 }
1454 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455}
1456
Tal Einat6dc57e22018-06-30 23:02:48 +03001457/*[clinic input]
1458select.epoll.register
1459
1460 fd: fildes
1461 the target file descriptor of the operation
Anthony Sottiled0518012020-06-23 14:49:56 -07001462 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +03001463 a bit set composed of the various EPOLL constants
1464
1465Registers a new fd or raises an OSError if the fd is already registered.
1466
1467The epoll interface supports all file descriptors that support poll.
1468[clinic start generated code]*/
1469
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001470static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001471select_epoll_register_impl(pyEpoll_Object *self, int fd,
1472 unsigned int eventmask)
Anthony Sottiled0518012020-06-23 14:49:56 -07001473/*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474{
Tal Einat6dc57e22018-06-30 23:02:48 +03001475 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001476}
1477
Tal Einat6dc57e22018-06-30 23:02:48 +03001478/*[clinic input]
1479select.epoll.modify
1480
1481 fd: fildes
1482 the target file descriptor of the operation
1483 eventmask: unsigned_int(bitwise=True)
1484 a bit set composed of the various EPOLL constants
1485
1486Modify event mask for a registered file descriptor.
1487[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001488
1489static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001490select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1491 unsigned int eventmask)
1492/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001493{
Tal Einat6dc57e22018-06-30 23:02:48 +03001494 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001495}
1496
Tal Einat6dc57e22018-06-30 23:02:48 +03001497/*[clinic input]
1498select.epoll.unregister
1499
1500 fd: fildes
1501 the target file descriptor of the operation
1502
1503Remove a registered file descriptor from the epoll object.
1504[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001505
1506static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001507select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1508/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509{
Tal Einat6dc57e22018-06-30 23:02:48 +03001510 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511}
1512
Tal Einat6dc57e22018-06-30 23:02:48 +03001513/*[clinic input]
1514select.epoll.poll
1515
1516 timeout as timeout_obj: object = None
1517 the maximum time to wait in seconds (as float);
1518 a timeout of None or -1 makes poll wait indefinitely
1519 maxevents: int = -1
1520 the maximum number of events returned; -1 means no limit
1521
1522Wait for events on the epoll file descriptor.
1523
1524Returns a list containing any descriptors that have events to report,
1525as a list of (fd, events) 2-tuples.
1526[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001527
1528static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001529select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1530 int maxevents)
1531/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 int nfds, i;
1534 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001535 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001536 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 if (self->epfd < 0)
1539 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001540
Berker Peksagb690b9b2018-09-11 20:29:48 +03001541 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001542 /* epoll_wait() has a resolution of 1 millisecond, round towards
1543 infinity to wait at least timeout seconds. */
1544 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001545 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001546 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1547 PyErr_SetString(PyExc_TypeError,
1548 "timeout must be an integer or None");
1549 }
1550 return NULL;
1551 }
1552
1553 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1554 if (ms < INT_MIN || ms > INT_MAX) {
1555 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1556 return NULL;
1557 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001558 /* epoll_wait(2) treats all arbitrary negative numbers the same
1559 for the timeout argument, but -1 is the documented way to block
1560 indefinitely in the epoll_wait(2) documentation, so we set ms
1561 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001562
Berker Peksagb690b9b2018-09-11 20:29:48 +03001563 Note that we didn't use INFTIM here since it's non-standard and
1564 isn't available under Linux. */
1565 if (ms < 0) {
1566 ms = -1;
1567 }
1568
1569 if (timeout >= 0) {
1570 deadline = _PyTime_GetMonotonicClock() + timeout;
1571 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001575 maxevents = FD_SETSIZE-1;
1576 }
1577 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 PyErr_Format(PyExc_ValueError,
1579 "maxevents must be greater than 0, got %d",
1580 maxevents);
1581 return NULL;
1582 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001584 evs = PyMem_New(struct epoll_event, maxevents);
1585 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001586 PyErr_NoMemory();
1587 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589
Victor Stinner41eba222015-03-30 21:59:21 +02001590 do {
1591 Py_BEGIN_ALLOW_THREADS
1592 errno = 0;
1593 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1594 Py_END_ALLOW_THREADS
1595
1596 if (errno != EINTR)
1597 break;
1598
1599 /* poll() was interrupted by a signal */
1600 if (PyErr_CheckSignals())
1601 goto error;
1602
1603 if (timeout >= 0) {
1604 timeout = deadline - _PyTime_GetMonotonicClock();
1605 if (timeout < 0) {
1606 nfds = 0;
1607 break;
1608 }
1609 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1610 /* retry epoll_wait() with the recomputed timeout */
1611 }
1612 } while(1);
1613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001615 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 goto error;
1617 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 elist = PyList_New(nfds);
1620 if (elist == NULL) {
1621 goto error;
1622 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001625 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 if (etuple == NULL) {
1627 Py_CLEAR(elist);
1628 goto error;
1629 }
1630 PyList_SET_ITEM(elist, i, etuple);
1631 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632
Christian Heimesf6cd9672008-03-26 13:45:42 +00001633 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001634 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001636}
1637
Tal Einat6dc57e22018-06-30 23:02:48 +03001638
1639/*[clinic input]
1640select.epoll.__enter__
1641
1642[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001643
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001644static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001645select_epoll___enter___impl(pyEpoll_Object *self)
1646/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001647{
1648 if (self->epfd < 0)
1649 return pyepoll_err_closed();
1650
1651 Py_INCREF(self);
1652 return (PyObject *)self;
1653}
1654
Tal Einat6dc57e22018-06-30 23:02:48 +03001655/*[clinic input]
1656select.epoll.__exit__
1657
1658 exc_type: object = None
1659 exc_value: object = None
1660 exc_tb: object = None
1661 /
1662
1663[clinic start generated code]*/
1664
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001665static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001666select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1667 PyObject *exc_value, PyObject *exc_tb)
1668/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001669{
Dino Viehlandf9190542019-09-14 15:20:27 +01001670 return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001671}
1672
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001673static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 {"closed", (getter)pyepoll_get_closed, NULL,
1675 "True if the epoll handler is closed"},
1676 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001677};
1678
Dino Viehlandf9190542019-09-14 15:20:27 +01001679PyDoc_STRVAR(pyepoll_doc,
1680"select.epoll(sizehint=-1, flags=0)\n\
1681\n\
1682Returns an epolling object\n\
1683\n\
1684sizehint must be a positive integer or -1 for the default size. The\n\
1685sizehint is used to optimize internal data structures. It doesn't limit\n\
1686the maximum number of monitored events.");
1687
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001688#endif /* HAVE_EPOLL */
1689
1690#ifdef HAVE_KQUEUE
1691/* **************************************************************************
1692 * kqueue interface for BSD
1693 *
1694 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1695 * All rights reserved.
1696 *
1697 * Redistribution and use in source and binary forms, with or without
1698 * modification, are permitted provided that the following conditions
1699 * are met:
1700 * 1. Redistributions of source code must retain the above copyright
1701 * notice, this list of conditions and the following disclaimer.
1702 * 2. Redistributions in binary form must reproduce the above copyright
1703 * notice, this list of conditions and the following disclaimer in the
1704 * documentation and/or other materials provided with the distribution.
1705 *
1706 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1707 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1708 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1709 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1710 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1711 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1712 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1713 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1714 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1715 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1716 * SUCH DAMAGE.
1717 */
1718
1719#ifdef HAVE_SYS_EVENT_H
1720#include <sys/event.h>
1721#endif
1722
1723PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001724"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001725\n\
1726This object is the equivalent of the struct kevent for the C API.\n\
1727\n\
1728See the kqueue manpage for more detailed information about the meaning\n\
1729of the arguments.\n\
1730\n\
1731One minor note: while you might hope that udata could store a\n\
1732reference to a python object, it cannot, because it is impossible to\n\
1733keep a proper reference count of the object once it's passed into the\n\
1734kernel. Therefore, I have restricted it to only storing an integer. I\n\
1735recommend ignoring it and simply using the 'ident' field to key off\n\
1736of. You could also set up a dictionary on the python side to store a\n\
1737udata->object mapping.");
1738
1739typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 PyObject_HEAD
1741 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001742} kqueue_event_Object;
1743
Dino Viehlandf9190542019-09-14 15:20:27 +01001744#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001745
1746typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 PyObject_HEAD
1748 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001749} kqueue_queue_Object;
1750
Dino Viehlandf9190542019-09-14 15:20:27 +01001751#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001752
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001753#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1754# error uintptr_t does not match void *!
1755#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1756# define T_UINTPTRT T_ULONGLONG
1757# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001758# define UINTPTRT_FMT_UNIT "K"
1759# define INTPTRT_FMT_UNIT "L"
1760#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1761# define T_UINTPTRT T_ULONG
1762# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001763# define UINTPTRT_FMT_UNIT "k"
1764# define INTPTRT_FMT_UNIT "l"
1765#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1766# define T_UINTPTRT T_UINT
1767# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001768# define UINTPTRT_FMT_UNIT "I"
1769# define INTPTRT_FMT_UNIT "i"
1770#else
1771# error uintptr_t does not match int, long, or long long!
1772#endif
1773
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001774#if SIZEOF_LONG_LONG == 8
1775# define T_INT64 T_LONGLONG
1776# define INT64_FMT_UNIT "L"
1777#elif SIZEOF_LONG == 8
1778# define T_INT64 T_LONG
1779# define INT64_FMT_UNIT "l"
1780#elif SIZEOF_INT == 8
1781# define T_INT64 T_INT
1782# define INT64_FMT_UNIT "i"
1783#else
1784# define INT64_FMT_UNIT "_"
1785#endif
1786
1787#if SIZEOF_LONG_LONG == 4
1788# define T_UINT32 T_ULONGLONG
1789# define UINT32_FMT_UNIT "K"
1790#elif SIZEOF_LONG == 4
1791# define T_UINT32 T_ULONG
1792# define UINT32_FMT_UNIT "k"
1793#elif SIZEOF_INT == 4
1794# define T_UINT32 T_UINT
1795# define UINT32_FMT_UNIT "I"
1796#else
1797# define UINT32_FMT_UNIT "_"
1798#endif
1799
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001800/*
1801 * kevent is not standard and its members vary across BSDs.
1802 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001803#ifdef __NetBSD__
1804# define FILTER_TYPE T_UINT32
1805# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1806# define FLAGS_TYPE T_UINT32
1807# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1808# define FFLAGS_TYPE T_UINT32
1809# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001810#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001811# define FILTER_TYPE T_SHORT
1812# define FILTER_FMT_UNIT "h"
1813# define FLAGS_TYPE T_USHORT
1814# define FLAGS_FMT_UNIT "H"
1815# define FFLAGS_TYPE T_UINT
1816# define FFLAGS_FMT_UNIT "I"
1817#endif
1818
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001819#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001820# define DATA_TYPE T_INT64
1821# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001822#else
1823# define DATA_TYPE T_INTPTRT
1824# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001825#endif
1826
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001827/* Unfortunately, we can't store python objects in udata, because
1828 * kevents in the kernel can be removed without warning, which would
1829 * forever lose the refcount on the object stored with it.
1830 */
1831
1832#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1833static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001834 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1835 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1836 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001838 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1840 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841};
1842#undef KQ_OFF
1843
1844static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001845
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001846kqueue_event_repr(kqueue_event_Object *s)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 char buf[1024];
1849 PyOS_snprintf(
1850 buf, sizeof(buf),
1851 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001852 "data=0x%llx udata=%p>",
1853 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1854 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856}
1857
1858static int
1859kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 PyObject *pfd;
1862 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1863 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001864 static const char fmt[] = "O|"
1865 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1866 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1871 &pfd, &(self->e.filter), &(self->e.flags),
1872 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1873 return -1;
1874 }
1875
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001876 if (PyLong_Check(pfd)) {
1877 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 }
1879 else {
1880 self->e.ident = PyObject_AsFileDescriptor(pfd);
1881 }
1882 if (PyErr_Occurred()) {
1883 return -1;
1884 }
1885 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001886}
1887
1888static PyObject *
1889kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001892 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001895 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001897
1898#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1899 result = CMP(s->e.ident, o->e.ident)
1900 : CMP(s->e.filter, o->e.filter)
1901 : CMP(s->e.flags, o->e.flags)
1902 : CMP(s->e.fflags, o->e.fflags)
1903 : CMP(s->e.data, o->e.data)
1904 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1905 : 0;
1906#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001907
stratakise8b19652017-11-02 11:32:54 +01001908 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001909}
1910
Dino Viehlandf9190542019-09-14 15:20:27 +01001911static PyType_Slot kqueue_event_Type_slots[] = {
1912 {Py_tp_doc, (void*)kqueue_event_doc},
1913 {Py_tp_init, kqueue_event_init},
1914 {Py_tp_members, kqueue_event_members},
1915 {Py_tp_new, PyType_GenericNew},
1916 {Py_tp_repr, kqueue_event_repr},
1917 {Py_tp_richcompare, kqueue_event_richcompare},
1918 {0, 0},
1919};
1920
1921static PyType_Spec kqueue_event_Type_spec = {
1922 "select.kevent",
1923 sizeof(kqueue_event_Object),
1924 0,
1925 Py_TPFLAGS_DEFAULT,
1926 kqueue_event_Type_slots
1927};
1928
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001929static PyObject *
1930kqueue_queue_err_closed(void)
1931{
Victor Stinner13423c32013-08-22 00:19:50 +02001932 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001934}
1935
1936static int
1937kqueue_queue_internal_close(kqueue_queue_Object *self)
1938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 int save_errno = 0;
1940 if (self->kqfd >= 0) {
1941 int kqfd = self->kqfd;
1942 self->kqfd = -1;
1943 Py_BEGIN_ALLOW_THREADS
1944 if (close(kqfd) < 0)
1945 save_errno = errno;
1946 Py_END_ALLOW_THREADS
1947 }
1948 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001949}
1950
1951static PyObject *
1952newKqueue_Object(PyTypeObject *type, SOCKET fd)
1953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001955 assert(type != NULL);
1956 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1957 assert(queue_alloc != NULL);
1958 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 if (self == NULL) {
1960 return NULL;
1961 }
1962
1963 if (fd == -1) {
1964 Py_BEGIN_ALLOW_THREADS
1965 self->kqfd = kqueue();
1966 Py_END_ALLOW_THREADS
1967 }
1968 else {
1969 self->kqfd = fd;
1970 }
1971 if (self->kqfd < 0) {
1972 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001973 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 return NULL;
1975 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001976
1977 if (fd == -1) {
1978 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1979 Py_DECREF(self);
1980 return NULL;
1981 }
1982 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001984}
1985
Tal Einat6dc57e22018-06-30 23:02:48 +03001986/*[clinic input]
1987@classmethod
1988select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001989
Tal Einat6dc57e22018-06-30 23:02:48 +03001990Kqueue syscall wrapper.
1991
1992For example, to start watching a socket for input:
1993>>> kq = kqueue()
1994>>> sock = socket()
1995>>> sock.connect((host, port))
1996>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
1997
1998To wait one second for it to become writeable:
1999>>> kq.control(None, 1, 1000)
2000
2001To stop listening:
2002>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2003[clinic start generated code]*/
2004
2005static PyObject *
2006select_kqueue_impl(PyTypeObject *type)
2007/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002010}
2011
2012static void
2013kqueue_queue_dealloc(kqueue_queue_Object *self)
2014{
Dino Viehlandf9190542019-09-14 15:20:27 +01002015 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002017 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2018 kqueue_free((PyObject *)self);
2019 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002020}
2021
Tal Einat6dc57e22018-06-30 23:02:48 +03002022/*[clinic input]
2023select.kqueue.close
2024
2025Close the kqueue control file descriptor.
2026
2027Further operations on the kqueue object will raise an exception.
2028[clinic start generated code]*/
2029
2030static PyObject *
2031select_kqueue_close_impl(kqueue_queue_Object *self)
2032/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 errno = kqueue_queue_internal_close(self);
2035 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002036 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 return NULL;
2038 }
2039 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040}
2041
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002042static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002043kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 if (self->kqfd < 0)
2046 Py_RETURN_TRUE;
2047 else
2048 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002049}
2050
Tal Einat6dc57e22018-06-30 23:02:48 +03002051/*[clinic input]
2052select.kqueue.fileno
2053
2054Return the kqueue control file descriptor.
2055[clinic start generated code]*/
2056
2057static PyObject *
2058select_kqueue_fileno_impl(kqueue_queue_Object *self)
2059/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 if (self->kqfd < 0)
2062 return kqueue_queue_err_closed();
2063 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002064}
2065
Tal Einat6dc57e22018-06-30 23:02:48 +03002066/*[clinic input]
2067@classmethod
2068select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002069
Tal Einat6dc57e22018-06-30 23:02:48 +03002070 fd: int
2071 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002072
Tal Einat6dc57e22018-06-30 23:02:48 +03002073Create a kqueue object from a given control fd.
2074[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002075
2076static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002077select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2078/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002079{
Tal Einat6dc57e22018-06-30 23:02:48 +03002080 SOCKET s_fd = (SOCKET)fd;
2081
2082 return newKqueue_Object(type, s_fd);
2083}
2084
2085/*[clinic input]
2086select.kqueue.control
2087
2088 changelist: object
2089 Must be an iterable of kevent objects describing the changes to be made
2090 to the kernel's watch list or None.
2091 maxevents: int
2092 The maximum number of events that the kernel will return.
2093 timeout as otimeout: object = None
2094 The maximum time to wait in seconds, or else None to wait forever.
2095 This accepts floats for smaller timeouts, too.
2096 /
2097
2098Calls the kernel kevent function.
2099[clinic start generated code]*/
2100
2101static PyObject *
2102select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2103 int maxevents, PyObject *otimeout)
2104/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 int gotevents = 0;
2107 int nchanges = 0;
2108 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002109 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 PyObject *result = NULL;
2111 struct kevent *evl = NULL;
2112 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002113 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002115 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 if (self->kqfd < 0)
2118 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002119
Tal Einat6dc57e22018-06-30 23:02:48 +03002120 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 PyErr_Format(PyExc_ValueError,
2122 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002123 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 return NULL;
2125 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Tal Einat6dc57e22018-06-30 23:02:48 +03002127 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 ptimeoutspec = NULL;
2129 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002130 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002131 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002132 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002133 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002134 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002135 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002136 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002137 return NULL;
2138 }
2139
Victor Stinner4448c082015-03-31 11:48:34 +02002140 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002141 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002142
Victor Stinner4448c082015-03-31 11:48:34 +02002143 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 PyErr_SetString(PyExc_ValueError,
2145 "timeout must be positive or None");
2146 return NULL;
2147 }
Victor Stinner4448c082015-03-31 11:48:34 +02002148 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002150
Tal Einat6dc57e22018-06-30 23:02:48 +03002151 if (changelist != Py_None) {
2152 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002153 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 return NULL;
2155 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002156 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2157 PyErr_SetString(PyExc_OverflowError,
2158 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 goto error;
2160 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002161 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 chl = PyMem_New(struct kevent, nchanges);
2164 if (chl == NULL) {
2165 PyErr_NoMemory();
2166 goto error;
2167 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002168 for (i = 0; i < nchanges; ++i) {
2169 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 PyErr_SetString(PyExc_TypeError,
2172 "changelist must be an iterable of "
2173 "select.kevent objects");
2174 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002176 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002178 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002182 if (maxevents) {
2183 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 if (evl == NULL) {
2185 PyErr_NoMemory();
2186 goto error;
2187 }
2188 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002189
Victor Stinner4448c082015-03-31 11:48:34 +02002190 if (ptimeoutspec)
2191 deadline = _PyTime_GetMonotonicClock() + timeout;
2192
2193 do {
2194 Py_BEGIN_ALLOW_THREADS
2195 errno = 0;
2196 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002197 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002198 Py_END_ALLOW_THREADS
2199
2200 if (errno != EINTR)
2201 break;
2202
2203 /* kevent() was interrupted by a signal */
2204 if (PyErr_CheckSignals())
2205 goto error;
2206
2207 if (ptimeoutspec) {
2208 timeout = deadline - _PyTime_GetMonotonicClock();
2209 if (timeout < 0) {
2210 gotevents = 0;
2211 break;
2212 }
2213 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2214 goto error;
2215 /* retry kevent() with the recomputed timeout */
2216 }
2217 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 if (gotevents == -1) {
2220 PyErr_SetFromErrno(PyExc_OSError);
2221 goto error;
2222 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 result = PyList_New(gotevents);
2225 if (result == NULL) {
2226 goto error;
2227 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 for (i = 0; i < gotevents; i++) {
2230 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Dino Viehlandf9190542019-09-14 15:20:27 +01002232 ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 if (ch == NULL) {
2234 goto error;
2235 }
2236 ch->e = evl[i];
2237 PyList_SET_ITEM(result, i, (PyObject *)ch);
2238 }
2239 PyMem_Free(chl);
2240 PyMem_Free(evl);
2241 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002242
2243 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 PyMem_Free(chl);
2245 PyMem_Free(evl);
2246 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002247 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002249}
2250
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002251static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 {"closed", (getter)kqueue_queue_get_closed, NULL,
2253 "True if the kqueue handler is closed"},
2254 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255};
2256
Tal Einat6dc57e22018-06-30 23:02:48 +03002257#endif /* HAVE_KQUEUE */
2258
2259
2260/* ************************************************************************ */
2261
2262#include "clinic/selectmodule.c.h"
2263
2264#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2265
2266static PyMethodDef poll_methods[] = {
2267 SELECT_POLL_REGISTER_METHODDEF
2268 SELECT_POLL_MODIFY_METHODDEF
2269 SELECT_POLL_UNREGISTER_METHODDEF
2270 SELECT_POLL_POLL_METHODDEF
2271 {NULL, NULL} /* sentinel */
2272};
2273
Dino Viehlandf9190542019-09-14 15:20:27 +01002274
2275static PyType_Slot poll_Type_slots[] = {
2276 {Py_tp_dealloc, poll_dealloc},
2277 {Py_tp_methods, poll_methods},
2278 {Py_tp_new, poll_new},
2279 {0, 0},
2280};
2281
2282static PyType_Spec poll_Type_spec = {
2283 "select.poll",
2284 sizeof(pollObject),
2285 0,
2286 Py_TPFLAGS_DEFAULT,
2287 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002288};
2289
2290#ifdef HAVE_SYS_DEVPOLL_H
2291
2292static PyMethodDef devpoll_methods[] = {
2293 SELECT_DEVPOLL_REGISTER_METHODDEF
2294 SELECT_DEVPOLL_MODIFY_METHODDEF
2295 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2296 SELECT_DEVPOLL_POLL_METHODDEF
2297 SELECT_DEVPOLL_CLOSE_METHODDEF
2298 SELECT_DEVPOLL_FILENO_METHODDEF
2299 {NULL, NULL} /* sentinel */
2300};
2301
Tal Einat6dc57e22018-06-30 23:02:48 +03002302#endif /* HAVE_SYS_DEVPOLL_H */
2303
2304#endif /* HAVE_POLL */
2305
2306#ifdef HAVE_EPOLL
2307
2308static PyMethodDef pyepoll_methods[] = {
2309 SELECT_EPOLL_FROMFD_METHODDEF
2310 SELECT_EPOLL_CLOSE_METHODDEF
2311 SELECT_EPOLL_FILENO_METHODDEF
2312 SELECT_EPOLL_MODIFY_METHODDEF
2313 SELECT_EPOLL_REGISTER_METHODDEF
2314 SELECT_EPOLL_UNREGISTER_METHODDEF
2315 SELECT_EPOLL_POLL_METHODDEF
2316 SELECT_EPOLL___ENTER___METHODDEF
2317 SELECT_EPOLL___EXIT___METHODDEF
2318 {NULL, NULL},
2319};
2320
Dino Viehlandf9190542019-09-14 15:20:27 +01002321static PyType_Slot pyEpoll_Type_slots[] = {
2322 {Py_tp_dealloc, pyepoll_dealloc},
2323 {Py_tp_doc, (void*)pyepoll_doc},
2324 {Py_tp_getattro, PyObject_GenericGetAttr},
2325 {Py_tp_getset, pyepoll_getsetlist},
2326 {Py_tp_methods, pyepoll_methods},
2327 {Py_tp_new, select_epoll},
2328 {0, 0},
2329};
2330
2331static PyType_Spec pyEpoll_Type_spec = {
2332 "select.epoll",
2333 sizeof(pyEpoll_Object),
2334 0,
2335 Py_TPFLAGS_DEFAULT,
2336 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002337};
2338
2339#endif /* HAVE_EPOLL */
2340
2341#ifdef HAVE_KQUEUE
2342
Tal Einat6dc57e22018-06-30 23:02:48 +03002343static PyMethodDef kqueue_queue_methods[] = {
2344 SELECT_KQUEUE_FROMFD_METHODDEF
2345 SELECT_KQUEUE_CLOSE_METHODDEF
2346 SELECT_KQUEUE_FILENO_METHODDEF
2347 SELECT_KQUEUE_CONTROL_METHODDEF
2348 {NULL, NULL},
2349};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002350
Dino Viehlandf9190542019-09-14 15:20:27 +01002351static PyType_Slot kqueue_queue_Type_slots[] = {
2352 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002353 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002354 {Py_tp_getset, kqueue_queue_getsetlist},
2355 {Py_tp_methods, kqueue_queue_methods},
2356 {Py_tp_new, select_kqueue},
2357 {0, 0},
2358};
2359
2360static PyType_Spec kqueue_queue_Type_spec = {
2361 "select.kqueue",
2362 sizeof(kqueue_queue_Object),
2363 0,
2364 Py_TPFLAGS_DEFAULT,
2365 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002366};
2367
2368#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002369
2370
2371
2372
2373
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002374/* ************************************************************************ */
2375
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002376
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002377static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002378 SELECT_SELECT_METHODDEF
2379 SELECT_POLL_METHODDEF
2380 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002382};
2383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002385"This module supports asynchronous I/O on multiple file descriptors.\n\
2386\n\
2387*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002388On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002389
Martin v. Löwis1a214512008-06-11 05:26:20 +00002390
Dino Viehlandf9190542019-09-14 15:20:27 +01002391
2392static int
2393_select_traverse(PyObject *module, visitproc visit, void *arg)
2394{
Hai Shif707d942020-03-16 21:15:01 +08002395 Py_VISIT(get_select_state(module)->close);
2396 Py_VISIT(get_select_state(module)->poll_Type);
2397 Py_VISIT(get_select_state(module)->devpoll_Type);
2398 Py_VISIT(get_select_state(module)->pyEpoll_Type);
2399 Py_VISIT(get_select_state(module)->kqueue_event_Type);
2400 Py_VISIT(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002401 return 0;
2402}
2403
2404static int
2405_select_clear(PyObject *module)
2406{
Hai Shif707d942020-03-16 21:15:01 +08002407 Py_CLEAR(get_select_state(module)->close);
2408 Py_CLEAR(get_select_state(module)->poll_Type);
2409 Py_CLEAR(get_select_state(module)->devpoll_Type);
2410 Py_CLEAR(get_select_state(module)->pyEpoll_Type);
2411 Py_CLEAR(get_select_state(module)->kqueue_event_Type);
2412 Py_CLEAR(get_select_state(module)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002413 return 0;
2414}
2415
2416static void
2417_select_free(void *module)
2418{
2419 _select_clear((PyObject *)module);
2420}
2421
Martin v. Löwis1a214512008-06-11 05:26:20 +00002422static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 PyModuleDef_HEAD_INIT,
2424 "select",
2425 module_doc,
Dino Viehlandf9190542019-09-14 15:20:27 +01002426 sizeof(_selectstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 select_methods,
2428 NULL,
Dino Viehlandf9190542019-09-14 15:20:27 +01002429 _select_traverse,
2430 _select_clear,
2431 _select_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002432};
2433
Mark Hammond62b1ab12002-07-23 06:31:15 +00002434PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002435PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 PyObject *m;
2438 m = PyModule_Create(&selectmodule);
2439 if (m == NULL)
2440 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002441
Hai Shif707d942020-03-16 21:15:01 +08002442 get_select_state(m)->close = PyUnicode_InternFromString("close");
Dino Viehlandf9190542019-09-14 15:20:27 +01002443
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002444 Py_INCREF(PyExc_OSError);
2445 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002446
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002447#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002448#ifdef HAVE_BROKEN_PIPE_BUF
2449#undef PIPE_BUF
2450#define PIPE_BUF 512
2451#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002452 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002453#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002454
Charles-François Natali986a56c2013-01-19 12:19:10 +01002455#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002456#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 if (select_have_broken_poll()) {
2458 if (PyObject_DelAttrString(m, "poll") == -1) {
2459 PyErr_Clear();
2460 }
2461 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002462#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002464#endif
Dino Viehlandf9190542019-09-14 15:20:27 +01002465 PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
2466 if (poll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002468 get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002469
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002470 PyModule_AddIntMacro(m, POLLIN);
2471 PyModule_AddIntMacro(m, POLLPRI);
2472 PyModule_AddIntMacro(m, POLLOUT);
2473 PyModule_AddIntMacro(m, POLLERR);
2474 PyModule_AddIntMacro(m, POLLHUP);
2475 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002476
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002477#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002478 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002479#endif
2480#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002481 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002482#endif
2483#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002484 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002485#endif
2486#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002487 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002488#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002489#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002490 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002491#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002492#ifdef POLLRDHUP
2493 /* Kernel 2.6.17+ */
2494 PyModule_AddIntMacro(m, POLLRDHUP);
2495#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002497#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002498
Jesus Cead8b9ae62011-11-14 19:07:41 +01002499#ifdef HAVE_SYS_DEVPOLL_H
Dino Viehlandf9190542019-09-14 15:20:27 +01002500 PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
2501 if (devpoll_Type == NULL)
Jesus Cead8b9ae62011-11-14 19:07:41 +01002502 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002503 get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
Jesus Cead8b9ae62011-11-14 19:07:41 +01002504#endif
2505
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002506#ifdef HAVE_EPOLL
Dino Viehlandf9190542019-09-14 15:20:27 +01002507 PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
2508 if (pyEpoll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002510 get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
Dino Viehlandf9190542019-09-14 15:20:27 +01002511 Py_INCREF(pyEpoll_Type);
Hai Shif707d942020-03-16 21:15:01 +08002512 PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002513
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002514 PyModule_AddIntMacro(m, EPOLLIN);
2515 PyModule_AddIntMacro(m, EPOLLOUT);
2516 PyModule_AddIntMacro(m, EPOLLPRI);
2517 PyModule_AddIntMacro(m, EPOLLERR);
2518 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002519#ifdef EPOLLRDHUP
2520 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002521 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002522#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002523 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002524#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002526 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002527#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002528#ifdef EPOLLEXCLUSIVE
2529 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2530#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002531
2532#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002533 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002534#endif
2535#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002536 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002537#endif
2538#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002539 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002540#endif
2541#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002542 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002543#endif
2544#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002545 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002546#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002547
Benjamin Peterson95c16622011-12-27 15:36:32 -06002548#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002549 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002550#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002551#endif /* HAVE_EPOLL */
2552
2553#ifdef HAVE_KQUEUE
Dino Viehlandf9190542019-09-14 15:20:27 +01002554 PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
2555 if (kqueue_event_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002557 get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
2558 Py_INCREF(get_select_state(m)->kqueue_event_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002559 PyModule_AddObject(m, "kevent", kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002560
Dino Viehlandf9190542019-09-14 15:20:27 +01002561 PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
2562 if (kqueue_queue_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 return NULL;
Hai Shif707d942020-03-16 21:15:01 +08002564 get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
2565 Py_INCREF(get_select_state(m)->kqueue_queue_Type);
Dino Viehlandf9190542019-09-14 15:20:27 +01002566 PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002567
2568 /* event filters */
2569 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2570 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002571#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
2574#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
2577#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002579#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002580#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002582#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002583#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002585#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 /* event flags */
2589 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2590 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2591 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2592 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2593 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2594 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002595
Berker Peksag7ec64562016-09-14 18:16:59 +03002596#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#endif
2599#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002601#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002603 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2604 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002607#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002609#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002612#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2615 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2616 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2617 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2618 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2619 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002620#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002623#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2625 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2626 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2627 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2628 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2631 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2632 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002633#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634
2635 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002636#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2638 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2639 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002640#endif
2641
2642#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002644}