blob: 7c6d7e4a15e96b5a765cb9c396463b0d505882b2 [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"
Christian Heimes4fbc72b2008-03-22 00:47:35 +000012#include <structmember.h>
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
72#define _selectstate(o) ((_selectstate *)PyModule_GetState(o))
73#define _selectstate_global _selectstate(PyState_FindModule(&selectmodule))
74
Tal Einat6dc57e22018-06-30 23:02:48 +030075/*[clinic input]
76module select
77class select.poll "pollObject *" "&poll_Type"
78class select.devpoll "devpollObject *" "&devpoll_Type"
79class select.epoll "pyEpoll_Object *" "&pyEpoll_Type"
Dino Viehlandf9190542019-09-14 15:20:27 +010080class select.kqueue "kqueue_queue_Object *" "_selectstate_global->kqueue_queue_Type"
Tal Einat6dc57e22018-06-30 23:02:48 +030081[clinic start generated code]*/
Dino Viehlandf9190542019-09-14 15:20:27 +010082/*[clinic end generated code: output=da39a3ee5e6b4b0d input=41071028e0ede093]*/
Tal Einat6dc57e22018-06-30 23:02:48 +030083
84static int
85fildes_converter(PyObject *o, void *p)
86{
87 int fd;
88 int *pointer = (int *)p;
89 fd = PyObject_AsFileDescriptor(o);
90 if (fd == -1)
91 return 0;
92 *pointer = fd;
93 return 1;
94}
95
96/*[python input]
97class fildes_converter(CConverter):
98 type = 'int'
99 converter = 'fildes_converter'
100[python start generated code]*/
101/*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/
102
Barry Warsawc1cb3601996-12-12 22:16:21 +0000103/* list of Python objects and their file descriptor */
104typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 PyObject *obj; /* owned reference */
106 SOCKET fd;
107 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000108} pylist;
109
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110static void
Tim Peters4b046c22001-08-16 21:59:46 +0000111reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200113 unsigned int i;
114 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200115 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 }
117 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118}
119
120
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000121/* returns -1 and sets the Python exception if an error occurred, otherwise
122 returns a number >= 0
123*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000124static int
Brett Cannon62dba4c2003-09-10 19:37:42 +0000125seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200128 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100129 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 PyObject* fast_seq = NULL;
131 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +0000132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
134 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135
Benjamin Petersone0edb8b2010-06-27 23:49:45 +0000136 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 if (!fast_seq)
138 return -1;
139
Antoine Pitroue4ad37e2012-11-01 20:13:54 +0100140 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 SOCKET v;
142
143 /* any intervening fileno() calls could decr this refcnt */
144 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200145 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 Py_INCREF(o);
148 v = PyObject_AsFileDescriptor( o );
149 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000150
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000151#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000153#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200154 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 PyErr_SetString(PyExc_ValueError,
156 "filedescriptor out of range in select()");
157 goto finally;
158 }
159 if (v > max)
160 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000161#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200165 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 PyErr_SetString(PyExc_ValueError,
167 "too many file descriptors in select()");
168 goto finally;
169 }
170 fd2obj[index].obj = o;
171 fd2obj[index].fd = v;
172 fd2obj[index].sentinel = 0;
173 fd2obj[++index].sentinel = -1;
174 }
175 Py_DECREF(fast_seq);
176 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177
178 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 Py_XDECREF(o);
180 Py_DECREF(fast_seq);
181 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000182}
183
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000184/* returns NULL and sets the Python exception if an error occurred */
185static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000186set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 int i, j, count=0;
189 PyObject *list, *o;
190 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
193 if (FD_ISSET(fd2obj[j].fd, set))
194 count++;
195 }
196 list = PyList_New(count);
197 if (!list)
198 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 i = 0;
201 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
202 fd = fd2obj[j].fd;
203 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 o = fd2obj[j].obj;
205 fd2obj[j].obj = NULL;
206 /* transfer ownership */
207 if (PyList_SetItem(list, i, o) < 0)
208 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 i++;
211 }
212 }
213 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000214 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 Py_DECREF(list);
216 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000217}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000218
Barry Warsawb44740f2001-08-16 16:52:59 +0000219#undef SELECT_USES_HEAP
220#if FD_SETSIZE > 1024
221#define SELECT_USES_HEAP
222#endif /* FD_SETSIZE > 1024 */
223
Tal Einat6dc57e22018-06-30 23:02:48 +0300224/*[clinic input]
225select.select
226
227 rlist: object
228 wlist: object
229 xlist: object
230 timeout as timeout_obj: object = None
231 /
232
233Wait until one or more file descriptors are ready for some kind of I/O.
234
235The first three arguments are sequences of file descriptors to be waited for:
236rlist -- wait until ready for reading
237wlist -- wait until ready for writing
238xlist -- wait for an "exceptional condition"
239If only one kind of condition is required, pass [] for the other lists.
240
241A file descriptor is either a socket or file object, or a small integer
242gotten from a fileno() method call on one of those.
243
244The optional 4th argument specifies a timeout in seconds; it may be
245a floating point number to specify fractions of seconds. If it is absent
246or None, the call will never time out.
247
248The return value is a tuple of three lists corresponding to the first three
249arguments; each contains the subset of the corresponding file descriptors
250that are ready.
251
252*** IMPORTANT NOTICE ***
253On Windows, only sockets are supported; on Unix, all file
254descriptors can be used.
255[clinic start generated code]*/
256
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000257static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300258select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
259 PyObject *xlist, PyObject *timeout_obj)
260/*[clinic end generated code: output=2b3cfa824f7ae4cf input=177e72184352df25]*/
Guido van Rossumed233a51992-06-23 09:07:03 +0000261{
Barry Warsawb44740f2001-08-16 16:52:59 +0000262#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000264#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 /* XXX: All this should probably be implemented as follows:
266 * - find the highest descriptor we're interested in
267 * - add one
268 * - that's the size
269 * See: Stevens, APitUE, $12.5.1
270 */
271 pylist rfd2obj[FD_SETSIZE + 1];
272 pylist wfd2obj[FD_SETSIZE + 1];
273 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000274#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 PyObject *ret = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 int imax, omax, emax, max;
279 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200280 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000281
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200282 if (timeout_obj == Py_None)
283 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200285 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100286 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200287 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
288 PyErr_SetString(PyExc_TypeError,
289 "timeout must be a float or None");
290 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100291 return NULL;
292 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100293
Pablo Galindo2c15b292017-10-17 15:14:41 +0100294 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100295 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100296 if (tv.tv_sec < 0) {
297 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 return NULL;
299 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 tvp = &tv;
301 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000302
Barry Warsawb44740f2001-08-16 16:52:59 +0000303#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 /* Allocate memory for the lists */
305 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
306 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
307 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
308 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
309 if (rfd2obj) PyMem_DEL(rfd2obj);
310 if (wfd2obj) PyMem_DEL(wfd2obj);
311 if (efd2obj) PyMem_DEL(efd2obj);
312 return PyErr_NoMemory();
313 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000314#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 /* Convert sequences to fd_sets, and get maximum fd number
317 * propagates the Python exception set in seq2set()
318 */
319 rfd2obj[0].sentinel = -1;
320 wfd2obj[0].sentinel = -1;
321 efd2obj[0].sentinel = -1;
Tal Einat6dc57e22018-06-30 23:02:48 +0300322 if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300324 if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 goto finally;
Tal Einat6dc57e22018-06-30 23:02:48 +0300326 if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 max = imax;
330 if (omax > max) max = omax;
331 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000332
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200333 if (tvp)
334 deadline = _PyTime_GetMonotonicClock() + timeout;
335
336 do {
337 Py_BEGIN_ALLOW_THREADS
338 errno = 0;
339 n = select(max, &ifdset, &ofdset, &efdset, tvp);
340 Py_END_ALLOW_THREADS
341
342 if (errno != EINTR)
343 break;
344
345 /* select() was interrupted by a signal */
346 if (PyErr_CheckSignals())
347 goto finally;
348
349 if (tvp) {
350 timeout = deadline - _PyTime_GetMonotonicClock();
351 if (timeout < 0) {
Oran Avraham7f524152018-12-05 22:36:03 +0200352 /* bpo-35310: lists were unmodified -- clear them explicitly */
353 FD_ZERO(&ifdset);
354 FD_ZERO(&ofdset);
355 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200356 n = 0;
357 break;
358 }
359 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200360 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200361 }
362 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000363
Thomas Heller106f4c72002-09-24 16:51:00 +0000364#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200366 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000368#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200370 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000372#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 else {
374 /* any of these three calls can raise an exception. it's more
375 convenient to test for this after all three calls... but
376 is that acceptable?
377 */
Tal Einat6dc57e22018-06-30 23:02:48 +0300378 rlist = set2list(&ifdset, rfd2obj);
379 wlist = set2list(&ofdset, wfd2obj);
380 xlist = set2list(&efdset, efd2obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (PyErr_Occurred())
382 ret = NULL;
383 else
Tal Einat6dc57e22018-06-30 23:02:48 +0300384 ret = PyTuple_Pack(3, rlist, wlist, xlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000385
Tal Einat6dc57e22018-06-30 23:02:48 +0300386 Py_XDECREF(rlist);
387 Py_XDECREF(wlist);
388 Py_XDECREF(xlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 }
390
Barry Warsawc1cb3601996-12-12 22:16:21 +0000391 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 reap_obj(rfd2obj);
393 reap_obj(wfd2obj);
394 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000395#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 PyMem_DEL(rfd2obj);
397 PyMem_DEL(wfd2obj);
398 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000399#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000401}
402
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000403#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000405 * poll() support
406 */
407
408typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 PyObject_HEAD
410 PyObject *dict;
411 int ufd_uptodate;
412 int ufd_len;
413 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300414 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000415} pollObject;
416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000418 contained within a pollObject. Return 1 on success, 0 on an error.
419*/
420
421static int
422update_ufd_array(pollObject *self)
423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 Py_ssize_t i, pos;
425 PyObject *key, *value;
426 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000427
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200428 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
430 if (self->ufds == NULL) {
431 self->ufds = old_ufds;
432 PyErr_NoMemory();
433 return 0;
434 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 i = pos = 0;
437 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200438 assert(i < self->ufd_len);
439 /* Never overflow */
440 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200441 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 i++;
443 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200444 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 self->ufd_uptodate = 1;
446 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000447}
448
Tal Einat6dc57e22018-06-30 23:02:48 +0300449/*[clinic input]
450select.poll.register
451
452 fd: fildes
453 either an integer, or an object with a fileno() method returning an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300454 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300455 an optional bitmask describing the type of events to check for
456 /
457
458Register a file descriptor with the polling object.
459[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000460
461static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300462select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300463/*[clinic end generated code: output=0dc7173c800a4a65 input=f18711d9bb021e25]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000464{
Tal Einat6dc57e22018-06-30 23:02:48 +0300465 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 /* Add entry to the internal dictionary: the key is the
469 file descriptor, and the value is the event mask. */
470 key = PyLong_FromLong(fd);
471 if (key == NULL)
472 return NULL;
Tal Einat6dc57e22018-06-30 23:02:48 +0300473 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (value == NULL) {
475 Py_DECREF(key);
476 return NULL;
477 }
478 err = PyDict_SetItem(self->dict, key, value);
479 Py_DECREF(key);
480 Py_DECREF(value);
481 if (err < 0)
482 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 self->ufd_uptodate = 0;
485
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200486 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487}
488
Tal Einat6dc57e22018-06-30 23:02:48 +0300489
490/*[clinic input]
491select.poll.modify
492
493 fd: fildes
494 either an integer, or an object with a fileno() method returning
495 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300496 eventmask: unsigned_short
Tal Einat6dc57e22018-06-30 23:02:48 +0300497 a bitmask describing the type of events to check for
498 /
499
500Modify an already registered file descriptor.
501[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000502
503static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300504select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300505/*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000506{
Tal Einat6dc57e22018-06-30 23:02:48 +0300507 PyObject *key, *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 /* Modify registered fd */
511 key = PyLong_FromLong(fd);
512 if (key == NULL)
513 return NULL;
Serhiy Storchakaa24107b2019-02-25 17:59:46 +0200514 if (PyDict_GetItemWithError(self->dict, key) == NULL) {
515 if (!PyErr_Occurred()) {
516 errno = ENOENT;
517 PyErr_SetFromErrno(PyExc_OSError);
518 }
Jesus Cea62a5c322012-07-19 21:31:26 +0200519 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 return NULL;
521 }
Tal Einat6dc57e22018-06-30 23:02:48 +0300522 value = PyLong_FromLong(eventmask);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 if (value == NULL) {
524 Py_DECREF(key);
525 return NULL;
526 }
527 err = PyDict_SetItem(self->dict, key, value);
528 Py_DECREF(key);
529 Py_DECREF(value);
530 if (err < 0)
531 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 self->ufd_uptodate = 0;
534
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200535 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000536}
537
538
Tal Einat6dc57e22018-06-30 23:02:48 +0300539/*[clinic input]
540select.poll.unregister
541
542 fd: fildes
543 /
544
545Remove a file descriptor being tracked by the polling object.
546[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000547
548static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300549select_poll_unregister_impl(pollObject *self, int fd)
550/*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 PyObject *key;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 /* Check whether the fd is already in the array */
555 key = PyLong_FromLong(fd);
556 if (key == NULL)
557 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 if (PyDict_DelItem(self->dict, key) == -1) {
560 Py_DECREF(key);
561 /* This will simply raise the KeyError set by PyDict_DelItem
562 if the file descriptor isn't registered. */
563 return NULL;
564 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 Py_DECREF(key);
567 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000568
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200569 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000570}
571
Tal Einat6dc57e22018-06-30 23:02:48 +0300572/*[clinic input]
573select.poll.poll
574
575 timeout as timeout_obj: object = None
576 /
577
578Polls the set of registered file descriptors.
579
580Returns a list containing any descriptors that have events or errors to
581report, as a list of (fd, event) 2-tuples.
582[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000583
584static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300585select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
586/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000587{
Tal Einat6dc57e22018-06-30 23:02:48 +0300588 PyObject *result_list = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200589 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200591 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200592 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000593
Tal Einat6dc57e22018-06-30 23:02:48 +0300594 if (timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200595 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100596 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200597 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
598 PyErr_SetString(PyExc_TypeError,
599 "timeout must be an integer or None");
600 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200602 }
603
Pablo Galindo2c15b292017-10-17 15:14:41 +0100604 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200605 if (ms < INT_MIN || ms > INT_MAX) {
606 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200608 }
609
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200610 if (timeout >= 0) {
611 deadline = _PyTime_GetMonotonicClock() + timeout;
612 }
613 }
614
615 /* On some OSes, typically BSD-based ones, the timeout parameter of the
616 poll() syscall, when negative, must be exactly INFTIM, where defined,
617 or -1. See issue 31334. */
618 if (ms < 0) {
619#ifdef INFTIM
620 ms = INFTIM;
621#else
622 ms = -1;
623#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000625
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300626 /* Avoid concurrent poll() invocation, issue 8865 */
627 if (self->poll_running) {
628 PyErr_SetString(PyExc_RuntimeError,
629 "concurrent poll() invocation");
630 return NULL;
631 }
632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 /* Ensure the ufd array is up to date */
634 if (!self->ufd_uptodate)
635 if (update_ufd_array(self) == 0)
636 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000637
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300638 self->poll_running = 1;
639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200641 async_err = 0;
642 do {
643 Py_BEGIN_ALLOW_THREADS
644 errno = 0;
645 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
646 Py_END_ALLOW_THREADS
647
648 if (errno != EINTR)
649 break;
650
651 /* poll() was interrupted by a signal */
652 if (PyErr_CheckSignals()) {
653 async_err = 1;
654 break;
655 }
656
657 if (timeout >= 0) {
658 timeout = deadline - _PyTime_GetMonotonicClock();
659 if (timeout < 0) {
660 poll_result = 0;
661 break;
662 }
663 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
664 /* retry poll() with the recomputed timeout */
665 }
666 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000667
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300668 self->poll_running = 0;
669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200671 if (!async_err)
672 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 return NULL;
674 }
675
676 /* build the result list */
677
678 result_list = PyList_New(poll_result);
679 if (!result_list)
680 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200682 for (i = 0, j = 0; j < poll_result; j++) {
683 /* skip to the next fired descriptor */
684 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 i++;
686 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200687 /* if we hit a NULL return, set value to NULL
688 and break out of loop; code at end will
689 clean up result_list */
690 value = PyTuple_New(2);
691 if (value == NULL)
692 goto error;
693 num = PyLong_FromLong(self->ufds[i].fd);
694 if (num == NULL) {
695 Py_DECREF(value);
696 goto error;
697 }
698 PyTuple_SET_ITEM(value, 0, num);
699
700 /* The &0xffff is a workaround for AIX. 'revents'
701 is a 16-bit short, and IBM assigned POLLNVAL
702 to be 0x8000, so the conversion to int results
703 in a negative number. See SF bug #923315. */
704 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
705 if (num == NULL) {
706 Py_DECREF(value);
707 goto error;
708 }
709 PyTuple_SET_ITEM(value, 1, num);
Zackery Spytz99d56b52018-12-08 07:16:55 -0700710 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200711 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 }
713 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000714
715 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 Py_DECREF(result_list);
717 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000718}
719
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000720static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000721newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 pollObject *self;
Dino Viehlandf9190542019-09-14 15:20:27 +0100724 self = PyObject_New(pollObject, _selectstate_global->poll_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 if (self == NULL)
726 return NULL;
727 /* ufd_uptodate is a Boolean, denoting whether the
728 array pointed to by ufds matches the contents of the dictionary. */
729 self->ufd_uptodate = 0;
730 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300731 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 self->dict = PyDict_New();
733 if (self->dict == NULL) {
734 Py_DECREF(self);
735 return NULL;
736 }
737 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000738}
739
Dino Viehlandf9190542019-09-14 15:20:27 +0100740static PyObject *
741poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
742{
743 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
744 return NULL;
745}
746
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000747static void
748poll_dealloc(pollObject *self)
749{
Dino Viehlandf9190542019-09-14 15:20:27 +0100750 PyObject* type = (PyObject *)Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 if (self->ufds != NULL)
752 PyMem_DEL(self->ufds);
753 Py_XDECREF(self->dict);
754 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +0100755 Py_DECREF(type);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000756}
757
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000758
Jesus Cead8b9ae62011-11-14 19:07:41 +0100759#ifdef HAVE_SYS_DEVPOLL_H
760typedef struct {
761 PyObject_HEAD
762 int fd_devpoll;
763 int max_n_fds;
764 int n_fds;
765 struct pollfd *fds;
766} devpollObject;
767
Victor Stinner13423c32013-08-22 00:19:50 +0200768static PyObject *
769devpoll_err_closed(void)
770{
771 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
772 return NULL;
773}
774
Jesus Cead8b9ae62011-11-14 19:07:41 +0100775static int devpoll_flush(devpollObject *self)
776{
777 int size, n;
778
779 if (!self->n_fds) return 0;
780
781 size = sizeof(struct pollfd)*self->n_fds;
782 self->n_fds = 0;
783
Victor Stinner54799672015-03-19 23:33:09 +0100784 n = _Py_write(self->fd_devpoll, self->fds, size);
785 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100786 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100787
Jesus Cead8b9ae62011-11-14 19:07:41 +0100788 if (n < size) {
789 /*
790 ** Data writed to /dev/poll is a binary data structure. It is not
791 ** clear what to do if a partial write occurred. For now, raise
792 ** an exception and see if we actually found this problem in
793 ** the wild.
794 ** See http://bugs.python.org/issue6397.
795 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300796 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100797 "Please, report at http://bugs.python.org/. "
798 "Data to report: Size tried: %d, actual size written: %d.",
799 size, n);
800 return -1;
801 }
802 return 0;
803}
804
805static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300806internal_devpoll_register(devpollObject *self, int fd,
807 unsigned short events, int remove)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100808{
Victor Stinner13423c32013-08-22 00:19:50 +0200809 if (self->fd_devpoll < 0)
810 return devpoll_err_closed();
811
Jesus Cead8b9ae62011-11-14 19:07:41 +0100812 if (remove) {
813 self->fds[self->n_fds].fd = fd;
814 self->fds[self->n_fds].events = POLLREMOVE;
815
816 if (++self->n_fds == self->max_n_fds) {
817 if (devpoll_flush(self))
818 return NULL;
819 }
820 }
821
822 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200823 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100824
825 if (++self->n_fds == self->max_n_fds) {
826 if (devpoll_flush(self))
827 return NULL;
828 }
829
830 Py_RETURN_NONE;
831}
832
Tal Einat6dc57e22018-06-30 23:02:48 +0300833/*[clinic input]
834select.devpoll.register
835
836 fd: fildes
837 either an integer, or an object with a fileno() method returning
838 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300839 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300840 an optional bitmask describing the type of events to check for
841 /
842
843Register a file descriptor with the polling object.
844[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100845
846static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300847select_devpoll_register_impl(devpollObject *self, int fd,
848 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300849/*[clinic end generated code: output=6e07fe8b74abba0c input=5bd7cacc47a8ee46]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100850{
Tal Einat6dc57e22018-06-30 23:02:48 +0300851 return internal_devpoll_register(self, fd, eventmask, 0);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100852}
853
Tal Einat6dc57e22018-06-30 23:02:48 +0300854/*[clinic input]
855select.devpoll.modify
Jesus Cead8b9ae62011-11-14 19:07:41 +0100856
Tal Einat6dc57e22018-06-30 23:02:48 +0300857 fd: fildes
858 either an integer, or an object with a fileno() method returning
859 an int
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300860 eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
Tal Einat6dc57e22018-06-30 23:02:48 +0300861 an optional bitmask describing the type of events to check for
862 /
863
864Modify a possible already registered file descriptor.
865[clinic start generated code]*/
866
867static PyObject *
868select_devpoll_modify_impl(devpollObject *self, int fd,
869 unsigned short eventmask)
Serhiy Storchaka7cb7bcf2018-07-26 13:22:16 +0300870/*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100871{
Tal Einat6dc57e22018-06-30 23:02:48 +0300872 return internal_devpoll_register(self, fd, eventmask, 1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100873}
874
Tal Einat6dc57e22018-06-30 23:02:48 +0300875/*[clinic input]
876select.devpoll.unregister
Jesus Cead8b9ae62011-11-14 19:07:41 +0100877
Tal Einat6dc57e22018-06-30 23:02:48 +0300878 fd: fildes
879 /
880
881Remove a file descriptor being tracked by the polling object.
882[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100883
884static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300885select_devpoll_unregister_impl(devpollObject *self, int fd)
886/*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100887{
Victor Stinner13423c32013-08-22 00:19:50 +0200888 if (self->fd_devpoll < 0)
889 return devpoll_err_closed();
890
Jesus Cead8b9ae62011-11-14 19:07:41 +0100891 self->fds[self->n_fds].fd = fd;
892 self->fds[self->n_fds].events = POLLREMOVE;
893
894 if (++self->n_fds == self->max_n_fds) {
895 if (devpoll_flush(self))
896 return NULL;
897 }
898
899 Py_RETURN_NONE;
900}
901
Tal Einat6dc57e22018-06-30 23:02:48 +0300902/*[clinic input]
903select.devpoll.poll
904 timeout as timeout_obj: object = None
905 /
906
907Polls the set of registered file descriptors.
908
909Returns a list containing any descriptors that have events or errors to
910report, as a list of (fd, event) 2-tuples.
911[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912
913static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +0300914select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
915/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +0100916{
917 struct dvpoll dvp;
Michael Osipov0e6e7a12018-08-17 13:43:02 +0200918 PyObject *result_list = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200921 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100922
Victor Stinner13423c32013-08-22 00:19:50 +0200923 if (self->fd_devpoll < 0)
924 return devpoll_err_closed();
925
Jesus Cead8b9ae62011-11-14 19:07:41 +0100926 /* Check values for timeout */
Tal Einat6dc57e22018-06-30 23:02:48 +0300927 if (timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200929 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100930 }
931 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200932 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100933 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200934 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
935 PyErr_SetString(PyExc_TypeError,
936 "timeout must be an integer or None");
937 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100938 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200939 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100940
Pablo Galindo2c15b292017-10-17 15:14:41 +0100941 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200942 if (ms < -1 || ms > INT_MAX) {
943 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
944 return NULL;
945 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100946 }
947
948 if (devpoll_flush(self))
949 return NULL;
950
951 dvp.dp_fds = self->fds;
952 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200953 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100954
Victor Stinner45ca48b2015-03-31 12:10:33 +0200955 if (timeout >= 0)
956 deadline = _PyTime_GetMonotonicClock() + timeout;
957
958 do {
959 /* call devpoll() */
960 Py_BEGIN_ALLOW_THREADS
961 errno = 0;
962 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
963 Py_END_ALLOW_THREADS
964
965 if (errno != EINTR)
966 break;
967
968 /* devpoll() was interrupted by a signal */
969 if (PyErr_CheckSignals())
970 return NULL;
971
972 if (timeout >= 0) {
973 timeout = deadline - _PyTime_GetMonotonicClock();
974 if (timeout < 0) {
975 poll_result = 0;
976 break;
977 }
978 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
979 dvp.dp_timeout = (int)ms;
980 /* retry devpoll() with the recomputed timeout */
981 }
982 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100983
984 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300985 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100986 return NULL;
987 }
988
989 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100990 result_list = PyList_New(poll_result);
991 if (!result_list)
992 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200993
994 for (i = 0; i < poll_result; i++) {
995 num1 = PyLong_FromLong(self->fds[i].fd);
996 num2 = PyLong_FromLong(self->fds[i].revents);
997 if ((num1 == NULL) || (num2 == NULL)) {
998 Py_XDECREF(num1);
999 Py_XDECREF(num2);
1000 goto error;
1001 }
1002 value = PyTuple_Pack(2, num1, num2);
1003 Py_DECREF(num1);
1004 Py_DECREF(num2);
1005 if (value == NULL)
1006 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001007 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001008 }
1009
1010 return result_list;
1011
1012 error:
1013 Py_DECREF(result_list);
1014 return NULL;
1015}
1016
Richard Oudkerk168d59b2013-08-22 13:31:15 +01001017static int
1018devpoll_internal_close(devpollObject *self)
1019{
1020 int save_errno = 0;
1021 if (self->fd_devpoll >= 0) {
1022 int fd = self->fd_devpoll;
1023 self->fd_devpoll = -1;
1024 Py_BEGIN_ALLOW_THREADS
1025 if (close(fd) < 0)
1026 save_errno = errno;
1027 Py_END_ALLOW_THREADS
1028 }
1029 return save_errno;
1030}
1031
Tal Einat6dc57e22018-06-30 23:02:48 +03001032/*[clinic input]
1033select.devpoll.close
1034
1035Close the devpoll file descriptor.
1036
1037Further operations on the devpoll object will raise an exception.
1038[clinic start generated code]*/
1039
1040static PyObject *
1041select_devpoll_close_impl(devpollObject *self)
1042/*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001043{
1044 errno = devpoll_internal_close(self);
1045 if (errno < 0) {
1046 PyErr_SetFromErrno(PyExc_OSError);
1047 return NULL;
1048 }
1049 Py_RETURN_NONE;
1050}
1051
Victor Stinner13423c32013-08-22 00:19:50 +02001052static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001053devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001054{
1055 if (self->fd_devpoll < 0)
1056 Py_RETURN_TRUE;
1057 else
1058 Py_RETURN_FALSE;
1059}
1060
Tal Einat6dc57e22018-06-30 23:02:48 +03001061/*[clinic input]
1062select.devpoll.fileno
1063
1064Return the file descriptor.
1065[clinic start generated code]*/
1066
1067static PyObject *
1068select_devpoll_fileno_impl(devpollObject *self)
1069/*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
Victor Stinner13423c32013-08-22 00:19:50 +02001070{
1071 if (self->fd_devpoll < 0)
1072 return devpoll_err_closed();
1073 return PyLong_FromLong(self->fd_devpoll);
1074}
1075
Victor Stinner13423c32013-08-22 00:19:50 +02001076static PyGetSetDef devpoll_getsetlist[] = {
1077 {"closed", (getter)devpoll_get_closed, NULL,
1078 "True if the devpoll object is closed"},
1079 {0},
1080};
1081
Jesus Cead8b9ae62011-11-14 19:07:41 +01001082static devpollObject *
1083newDevPollObject(void)
1084{
1085 devpollObject *self;
1086 int fd_devpoll, limit_result;
1087 struct pollfd *fds;
1088 struct rlimit limit;
1089
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090 /*
1091 ** If we try to process more that getrlimit()
1092 ** fds, the kernel will give an error, so
1093 ** we set the limit here. It is a dynamic
1094 ** value, because we can change rlimit() anytime.
1095 */
1096 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001097 if (limit_result == -1) {
1098 PyErr_SetFromErrno(PyExc_OSError);
1099 return NULL;
1100 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001101
1102 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1103 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001104 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001105
1106 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1107 if (fds == NULL) {
1108 close(fd_devpoll);
1109 PyErr_NoMemory();
1110 return NULL;
1111 }
1112
Dino Viehlandf9190542019-09-14 15:20:27 +01001113 self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001114 if (self == NULL) {
1115 close(fd_devpoll);
1116 PyMem_DEL(fds);
1117 return NULL;
1118 }
1119 self->fd_devpoll = fd_devpoll;
1120 self->max_n_fds = limit.rlim_cur;
1121 self->n_fds = 0;
1122 self->fds = fds;
1123
1124 return self;
1125}
1126
Dino Viehlandf9190542019-09-14 15:20:27 +01001127static PyObject *
1128devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1129{
1130 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s' instances", _PyType_Name(type));
1131 return NULL;
1132}
1133
Jesus Cead8b9ae62011-11-14 19:07:41 +01001134static void
1135devpoll_dealloc(devpollObject *self)
1136{
Dino Viehlandf9190542019-09-14 15:20:27 +01001137 PyObject *type = (PyObject *)Py_TYPE(self);
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001138 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001139 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001140 PyObject_Del(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001141 Py_DECREF(type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001142}
1143
Dino Viehlandf9190542019-09-14 15:20:27 +01001144static PyType_Slot devpoll_Type_slots[] = {
1145 {Py_tp_dealloc, devpoll_dealloc},
1146 {Py_tp_getset, devpoll_getsetlist},
1147 {Py_tp_methods, devpoll_methods},
1148 {Py_tp_new, devpoll_new},
1149 {0, 0},
1150};
1151
1152static PyType_Spec devpoll_Type_spec = {
1153 "select.devpoll",
1154 sizeof(devpollObject),
1155 0,
1156 Py_TPFLAGS_DEFAULT,
1157 devpoll_Type_slots
1158};
1159
Jesus Cead8b9ae62011-11-14 19:07:41 +01001160#endif /* HAVE_SYS_DEVPOLL_H */
1161
1162
Tal Einat6dc57e22018-06-30 23:02:48 +03001163/*[clinic input]
1164select.poll
Jesus Cead8b9ae62011-11-14 19:07:41 +01001165
Tal Einat6dc57e22018-06-30 23:02:48 +03001166Returns a polling object.
1167
1168This object supports registering and unregistering file descriptors, and then
1169polling them for I/O events.
1170[clinic start generated code]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001171
1172static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001173select_poll_impl(PyObject *module)
1174/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001177}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001178
Jesus Cead8b9ae62011-11-14 19:07:41 +01001179#ifdef HAVE_SYS_DEVPOLL_H
Tal Einat6dc57e22018-06-30 23:02:48 +03001180
1181/*[clinic input]
1182select.devpoll
1183
1184Returns a polling object.
1185
1186This object supports registering and unregistering file descriptors, and then
1187polling them for I/O events.
1188[clinic start generated code]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001189
1190static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001191select_devpoll_impl(PyObject *module)
1192/*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
Jesus Cead8b9ae62011-11-14 19:07:41 +01001193{
1194 return (PyObject *)newDevPollObject();
1195}
1196#endif
1197
1198
Thomas Wouters477c8d52006-05-27 19:21:47 +00001199#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001201 * On some systems poll() sets errno on invalid file descriptors. We test
1202 * for this at runtime because this bug may be fixed or introduced between
1203 * OS releases.
1204 */
1205static int select_have_broken_poll(void)
1206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 int poll_test;
1208 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 /* Create a file descriptor to make invalid */
1213 if (pipe(filedes) < 0) {
1214 return 1;
1215 }
1216 poll_struct.fd = filedes[0];
1217 close(filedes[0]);
1218 close(filedes[1]);
1219 poll_test = poll(&poll_struct, 1, 0);
1220 if (poll_test < 0) {
1221 return 1;
1222 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1223 return 1;
1224 }
1225 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001226}
1227#endif /* __APPLE__ */
1228
1229#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001230
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231#ifdef HAVE_EPOLL
1232/* **************************************************************************
1233 * epoll interface for Linux 2.6
1234 *
1235 * Written by Christian Heimes
1236 * Inspired by Twisted's _epoll.pyx and select.poll()
1237 */
1238
1239#ifdef HAVE_SYS_EPOLL_H
1240#include <sys/epoll.h>
1241#endif
1242
1243typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001245 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001246} pyEpoll_Object;
1247
Dino Viehlandf9190542019-09-14 15:20:27 +01001248#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001249
1250static PyObject *
1251pyepoll_err_closed(void)
1252{
Victor Stinner13423c32013-08-22 00:19:50 +02001253 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001255}
1256
1257static int
1258pyepoll_internal_close(pyEpoll_Object *self)
1259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 int save_errno = 0;
1261 if (self->epfd >= 0) {
1262 int epfd = self->epfd;
1263 self->epfd = -1;
1264 Py_BEGIN_ALLOW_THREADS
1265 if (close(epfd) < 0)
1266 save_errno = errno;
1267 Py_END_ALLOW_THREADS
1268 }
1269 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001270}
1271
1272static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001273newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 pyEpoll_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001276 assert(type != NULL);
1277 allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1278 assert(epoll_alloc != NULL);
1279 self = (pyEpoll_Object *) epoll_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 if (self == NULL)
1281 return NULL;
1282
1283 if (fd == -1) {
1284 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001285#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001286 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1287#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001288 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001289#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 Py_END_ALLOW_THREADS
1291 }
1292 else {
1293 self->epfd = fd;
1294 }
1295 if (self->epfd < 0) {
1296 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001297 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 return NULL;
1299 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001300
1301#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001302 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001303 Py_DECREF(self);
1304 return NULL;
1305 }
1306#endif
1307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001309}
1310
1311
Tal Einat6dc57e22018-06-30 23:02:48 +03001312/*[clinic input]
1313@classmethod
1314select.epoll.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001315
Tal Einat6dc57e22018-06-30 23:02:48 +03001316 sizehint: int = -1
1317 The expected number of events to be registered. It must be positive,
1318 or -1 to use the default. It is only used on older systems where
1319 epoll_create1() is not available; otherwise it has no effect (though its
1320 value is still checked).
1321 flags: int = 0
1322 Deprecated and completely ignored. However, when supplied, its value
1323 must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1324
1325Returns an epolling object.
1326[clinic start generated code]*/
1327
1328static PyObject *
1329select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1330/*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1331{
Tal Einat0cdf5f42018-06-30 15:43:23 +03001332 if (sizehint == -1) {
1333 sizehint = FD_SETSIZE - 1;
1334 }
1335 else if (sizehint <= 0) {
Tal Einat6dc57e22018-06-30 23:02:48 +03001336 PyErr_SetString(PyExc_ValueError, "negative sizehint");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001337 return NULL;
1338 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001339
1340#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001341 if (flags && flags != EPOLL_CLOEXEC) {
1342 PyErr_SetString(PyExc_OSError, "invalid flags");
1343 return NULL;
1344 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001345#endif
Tal Einat6dc57e22018-06-30 23:02:48 +03001346
Berker Peksage2197d12016-09-26 23:30:41 +03001347 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001348}
1349
1350
1351static void
1352pyepoll_dealloc(pyEpoll_Object *self)
1353{
Dino Viehlandf9190542019-09-14 15:20:27 +01001354 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 (void)pyepoll_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01001356 freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1357 epoll_free((PyObject *)self);
1358 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001359}
1360
Tal Einat6dc57e22018-06-30 23:02:48 +03001361/*[clinic input]
1362select.epoll.close
1363
1364Close the epoll control file descriptor.
1365
1366Further operations on the epoll object will raise an exception.
1367[clinic start generated code]*/
1368
1369static PyObject *
1370select_epoll_close_impl(pyEpoll_Object *self)
1371/*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 errno = pyepoll_internal_close(self);
1374 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001375 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 return NULL;
1377 }
1378 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379}
1380
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001381
1382static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001383pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 if (self->epfd < 0)
1386 Py_RETURN_TRUE;
1387 else
1388 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389}
1390
Tal Einat6dc57e22018-06-30 23:02:48 +03001391/*[clinic input]
1392select.epoll.fileno
1393
1394Return the epoll control file descriptor.
1395[clinic start generated code]*/
1396
1397static PyObject *
1398select_epoll_fileno_impl(pyEpoll_Object *self)
1399/*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001400{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 if (self->epfd < 0)
1402 return pyepoll_err_closed();
1403 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001404}
1405
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001406
Tal Einat6dc57e22018-06-30 23:02:48 +03001407/*[clinic input]
1408@classmethod
1409select.epoll.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001410
Tal Einat6dc57e22018-06-30 23:02:48 +03001411 fd: int
1412 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001413
Tal Einat6dc57e22018-06-30 23:02:48 +03001414Create an epoll object from a given control fd.
1415[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001416
1417static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001418select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1419/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1420{
1421 SOCKET s_fd = (SOCKET)fd;
1422 return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1423}
1424
1425
1426static PyObject *
1427pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 struct epoll_event ev;
1430 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 if (epfd < 0)
1433 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001434
Guido van Rossumee07b942013-12-06 17:46:22 -08001435 switch (op) {
1436 case EPOLL_CTL_ADD:
1437 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 ev.events = events;
1439 ev.data.fd = fd;
1440 Py_BEGIN_ALLOW_THREADS
1441 result = epoll_ctl(epfd, op, fd, &ev);
1442 Py_END_ALLOW_THREADS
1443 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001444 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1446 * operation required a non-NULL pointer in event, even
1447 * though this argument is ignored. */
1448 Py_BEGIN_ALLOW_THREADS
1449 result = epoll_ctl(epfd, op, fd, &ev);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 Py_END_ALLOW_THREADS
1451 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001452 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 result = -1;
1454 errno = EINVAL;
1455 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001458 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 return NULL;
1460 }
1461 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001462}
1463
Tal Einat6dc57e22018-06-30 23:02:48 +03001464/*[clinic input]
1465select.epoll.register
1466
1467 fd: fildes
1468 the target file descriptor of the operation
1469 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1470 a bit set composed of the various EPOLL constants
1471
1472Registers a new fd or raises an OSError if the fd is already registered.
1473
1474The epoll interface supports all file descriptors that support poll.
1475[clinic start generated code]*/
1476
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001477static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001478select_epoll_register_impl(pyEpoll_Object *self, int fd,
1479 unsigned int eventmask)
1480/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001481{
Tal Einat6dc57e22018-06-30 23:02:48 +03001482 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001483}
1484
Tal Einat6dc57e22018-06-30 23:02:48 +03001485/*[clinic input]
1486select.epoll.modify
1487
1488 fd: fildes
1489 the target file descriptor of the operation
1490 eventmask: unsigned_int(bitwise=True)
1491 a bit set composed of the various EPOLL constants
1492
1493Modify event mask for a registered file descriptor.
1494[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001495
1496static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001497select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1498 unsigned int eventmask)
1499/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001500{
Tal Einat6dc57e22018-06-30 23:02:48 +03001501 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502}
1503
Tal Einat6dc57e22018-06-30 23:02:48 +03001504/*[clinic input]
1505select.epoll.unregister
1506
1507 fd: fildes
1508 the target file descriptor of the operation
1509
1510Remove a registered file descriptor from the epoll object.
1511[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001512
1513static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001514select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1515/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001516{
Tal Einat6dc57e22018-06-30 23:02:48 +03001517 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001518}
1519
Tal Einat6dc57e22018-06-30 23:02:48 +03001520/*[clinic input]
1521select.epoll.poll
1522
1523 timeout as timeout_obj: object = None
1524 the maximum time to wait in seconds (as float);
1525 a timeout of None or -1 makes poll wait indefinitely
1526 maxevents: int = -1
1527 the maximum number of events returned; -1 means no limit
1528
1529Wait for events on the epoll file descriptor.
1530
1531Returns a list containing any descriptors that have events to report,
1532as a list of (fd, events) 2-tuples.
1533[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001534
1535static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001536select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1537 int maxevents)
1538/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 int nfds, i;
1541 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001542 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001543 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 if (self->epfd < 0)
1546 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001547
Berker Peksagb690b9b2018-09-11 20:29:48 +03001548 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001549 /* epoll_wait() has a resolution of 1 millisecond, round towards
1550 infinity to wait at least timeout seconds. */
1551 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001552 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001553 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1554 PyErr_SetString(PyExc_TypeError,
1555 "timeout must be an integer or None");
1556 }
1557 return NULL;
1558 }
1559
1560 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1561 if (ms < INT_MIN || ms > INT_MAX) {
1562 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1563 return NULL;
1564 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001565 /* epoll_wait(2) treats all arbitrary negative numbers the same
1566 for the timeout argument, but -1 is the documented way to block
1567 indefinitely in the epoll_wait(2) documentation, so we set ms
1568 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001569
Berker Peksagb690b9b2018-09-11 20:29:48 +03001570 Note that we didn't use INFTIM here since it's non-standard and
1571 isn't available under Linux. */
1572 if (ms < 0) {
1573 ms = -1;
1574 }
1575
1576 if (timeout >= 0) {
1577 deadline = _PyTime_GetMonotonicClock() + timeout;
1578 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001582 maxevents = FD_SETSIZE-1;
1583 }
1584 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 PyErr_Format(PyExc_ValueError,
1586 "maxevents must be greater than 0, got %d",
1587 maxevents);
1588 return NULL;
1589 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001590
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001591 evs = PyMem_New(struct epoll_event, maxevents);
1592 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001593 PyErr_NoMemory();
1594 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596
Victor Stinner41eba222015-03-30 21:59:21 +02001597 do {
1598 Py_BEGIN_ALLOW_THREADS
1599 errno = 0;
1600 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1601 Py_END_ALLOW_THREADS
1602
1603 if (errno != EINTR)
1604 break;
1605
1606 /* poll() was interrupted by a signal */
1607 if (PyErr_CheckSignals())
1608 goto error;
1609
1610 if (timeout >= 0) {
1611 timeout = deadline - _PyTime_GetMonotonicClock();
1612 if (timeout < 0) {
1613 nfds = 0;
1614 break;
1615 }
1616 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1617 /* retry epoll_wait() with the recomputed timeout */
1618 }
1619 } while(1);
1620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001622 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 goto error;
1624 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 elist = PyList_New(nfds);
1627 if (elist == NULL) {
1628 goto error;
1629 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001632 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 if (etuple == NULL) {
1634 Py_CLEAR(elist);
1635 goto error;
1636 }
1637 PyList_SET_ITEM(elist, i, etuple);
1638 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001639
Christian Heimesf6cd9672008-03-26 13:45:42 +00001640 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001641 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001643}
1644
Tal Einat6dc57e22018-06-30 23:02:48 +03001645
1646/*[clinic input]
1647select.epoll.__enter__
1648
1649[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001650
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001651static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001652select_epoll___enter___impl(pyEpoll_Object *self)
1653/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001654{
1655 if (self->epfd < 0)
1656 return pyepoll_err_closed();
1657
1658 Py_INCREF(self);
1659 return (PyObject *)self;
1660}
1661
Tal Einat6dc57e22018-06-30 23:02:48 +03001662/*[clinic input]
1663select.epoll.__exit__
1664
1665 exc_type: object = None
1666 exc_value: object = None
1667 exc_tb: object = None
1668 /
1669
1670[clinic start generated code]*/
1671
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001672static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001673select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1674 PyObject *exc_value, PyObject *exc_tb)
1675/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001676{
Dino Viehlandf9190542019-09-14 15:20:27 +01001677 return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001678}
1679
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001680static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 {"closed", (getter)pyepoll_get_closed, NULL,
1682 "True if the epoll handler is closed"},
1683 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001684};
1685
Dino Viehlandf9190542019-09-14 15:20:27 +01001686PyDoc_STRVAR(pyepoll_doc,
1687"select.epoll(sizehint=-1, flags=0)\n\
1688\n\
1689Returns an epolling object\n\
1690\n\
1691sizehint must be a positive integer or -1 for the default size. The\n\
1692sizehint is used to optimize internal data structures. It doesn't limit\n\
1693the maximum number of monitored events.");
1694
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001695#endif /* HAVE_EPOLL */
1696
1697#ifdef HAVE_KQUEUE
1698/* **************************************************************************
1699 * kqueue interface for BSD
1700 *
1701 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1702 * All rights reserved.
1703 *
1704 * Redistribution and use in source and binary forms, with or without
1705 * modification, are permitted provided that the following conditions
1706 * are met:
1707 * 1. Redistributions of source code must retain the above copyright
1708 * notice, this list of conditions and the following disclaimer.
1709 * 2. Redistributions in binary form must reproduce the above copyright
1710 * notice, this list of conditions and the following disclaimer in the
1711 * documentation and/or other materials provided with the distribution.
1712 *
1713 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1714 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1715 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1716 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1717 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1718 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1719 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1720 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1721 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1722 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1723 * SUCH DAMAGE.
1724 */
1725
1726#ifdef HAVE_SYS_EVENT_H
1727#include <sys/event.h>
1728#endif
1729
1730PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001731"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001732\n\
1733This object is the equivalent of the struct kevent for the C API.\n\
1734\n\
1735See the kqueue manpage for more detailed information about the meaning\n\
1736of the arguments.\n\
1737\n\
1738One minor note: while you might hope that udata could store a\n\
1739reference to a python object, it cannot, because it is impossible to\n\
1740keep a proper reference count of the object once it's passed into the\n\
1741kernel. Therefore, I have restricted it to only storing an integer. I\n\
1742recommend ignoring it and simply using the 'ident' field to key off\n\
1743of. You could also set up a dictionary on the python side to store a\n\
1744udata->object mapping.");
1745
1746typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 PyObject_HEAD
1748 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001749} kqueue_event_Object;
1750
Dino Viehlandf9190542019-09-14 15:20:27 +01001751#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001752
1753typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 PyObject_HEAD
1755 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001756} kqueue_queue_Object;
1757
Dino Viehlandf9190542019-09-14 15:20:27 +01001758#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001759
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001760#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1761# error uintptr_t does not match void *!
1762#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1763# define T_UINTPTRT T_ULONGLONG
1764# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001765# define UINTPTRT_FMT_UNIT "K"
1766# define INTPTRT_FMT_UNIT "L"
1767#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1768# define T_UINTPTRT T_ULONG
1769# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001770# define UINTPTRT_FMT_UNIT "k"
1771# define INTPTRT_FMT_UNIT "l"
1772#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1773# define T_UINTPTRT T_UINT
1774# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001775# define UINTPTRT_FMT_UNIT "I"
1776# define INTPTRT_FMT_UNIT "i"
1777#else
1778# error uintptr_t does not match int, long, or long long!
1779#endif
1780
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001781#if SIZEOF_LONG_LONG == 8
1782# define T_INT64 T_LONGLONG
1783# define INT64_FMT_UNIT "L"
1784#elif SIZEOF_LONG == 8
1785# define T_INT64 T_LONG
1786# define INT64_FMT_UNIT "l"
1787#elif SIZEOF_INT == 8
1788# define T_INT64 T_INT
1789# define INT64_FMT_UNIT "i"
1790#else
1791# define INT64_FMT_UNIT "_"
1792#endif
1793
1794#if SIZEOF_LONG_LONG == 4
1795# define T_UINT32 T_ULONGLONG
1796# define UINT32_FMT_UNIT "K"
1797#elif SIZEOF_LONG == 4
1798# define T_UINT32 T_ULONG
1799# define UINT32_FMT_UNIT "k"
1800#elif SIZEOF_INT == 4
1801# define T_UINT32 T_UINT
1802# define UINT32_FMT_UNIT "I"
1803#else
1804# define UINT32_FMT_UNIT "_"
1805#endif
1806
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001807/*
1808 * kevent is not standard and its members vary across BSDs.
1809 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001810#ifdef __NetBSD__
1811# define FILTER_TYPE T_UINT32
1812# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1813# define FLAGS_TYPE T_UINT32
1814# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1815# define FFLAGS_TYPE T_UINT32
1816# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001817#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001818# define FILTER_TYPE T_SHORT
1819# define FILTER_FMT_UNIT "h"
1820# define FLAGS_TYPE T_USHORT
1821# define FLAGS_FMT_UNIT "H"
1822# define FFLAGS_TYPE T_UINT
1823# define FFLAGS_FMT_UNIT "I"
1824#endif
1825
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001826#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001827# define DATA_TYPE T_INT64
1828# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001829#else
1830# define DATA_TYPE T_INTPTRT
1831# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001832#endif
1833
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001834/* Unfortunately, we can't store python objects in udata, because
1835 * kevents in the kernel can be removed without warning, which would
1836 * forever lose the refcount on the object stored with it.
1837 */
1838
1839#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1840static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001841 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1842 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1843 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001845 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1847 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001848};
1849#undef KQ_OFF
1850
1851static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001852
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853kqueue_event_repr(kqueue_event_Object *s)
1854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 char buf[1024];
1856 PyOS_snprintf(
1857 buf, sizeof(buf),
1858 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001859 "data=0x%llx udata=%p>",
1860 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1861 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001863}
1864
1865static int
1866kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 PyObject *pfd;
1869 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1870 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001871 static const char fmt[] = "O|"
1872 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1873 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1878 &pfd, &(self->e.filter), &(self->e.flags),
1879 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1880 return -1;
1881 }
1882
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001883 if (PyLong_Check(pfd)) {
1884 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 }
1886 else {
1887 self->e.ident = PyObject_AsFileDescriptor(pfd);
1888 }
1889 if (PyErr_Occurred()) {
1890 return -1;
1891 }
1892 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893}
1894
1895static PyObject *
1896kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001899 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001902 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001904
1905#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1906 result = CMP(s->e.ident, o->e.ident)
1907 : CMP(s->e.filter, o->e.filter)
1908 : CMP(s->e.flags, o->e.flags)
1909 : CMP(s->e.fflags, o->e.fflags)
1910 : CMP(s->e.data, o->e.data)
1911 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1912 : 0;
1913#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001914
stratakise8b19652017-11-02 11:32:54 +01001915 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001916}
1917
Dino Viehlandf9190542019-09-14 15:20:27 +01001918static PyType_Slot kqueue_event_Type_slots[] = {
1919 {Py_tp_doc, (void*)kqueue_event_doc},
1920 {Py_tp_init, kqueue_event_init},
1921 {Py_tp_members, kqueue_event_members},
1922 {Py_tp_new, PyType_GenericNew},
1923 {Py_tp_repr, kqueue_event_repr},
1924 {Py_tp_richcompare, kqueue_event_richcompare},
1925 {0, 0},
1926};
1927
1928static PyType_Spec kqueue_event_Type_spec = {
1929 "select.kevent",
1930 sizeof(kqueue_event_Object),
1931 0,
1932 Py_TPFLAGS_DEFAULT,
1933 kqueue_event_Type_slots
1934};
1935
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001936static PyObject *
1937kqueue_queue_err_closed(void)
1938{
Victor Stinner13423c32013-08-22 00:19:50 +02001939 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001941}
1942
1943static int
1944kqueue_queue_internal_close(kqueue_queue_Object *self)
1945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 int save_errno = 0;
1947 if (self->kqfd >= 0) {
1948 int kqfd = self->kqfd;
1949 self->kqfd = -1;
1950 Py_BEGIN_ALLOW_THREADS
1951 if (close(kqfd) < 0)
1952 save_errno = errno;
1953 Py_END_ALLOW_THREADS
1954 }
1955 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001956}
1957
1958static PyObject *
1959newKqueue_Object(PyTypeObject *type, SOCKET fd)
1960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001962 assert(type != NULL);
1963 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1964 assert(queue_alloc != NULL);
1965 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 if (self == NULL) {
1967 return NULL;
1968 }
1969
1970 if (fd == -1) {
1971 Py_BEGIN_ALLOW_THREADS
1972 self->kqfd = kqueue();
1973 Py_END_ALLOW_THREADS
1974 }
1975 else {
1976 self->kqfd = fd;
1977 }
1978 if (self->kqfd < 0) {
1979 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001980 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 return NULL;
1982 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001983
1984 if (fd == -1) {
1985 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1986 Py_DECREF(self);
1987 return NULL;
1988 }
1989 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001991}
1992
Tal Einat6dc57e22018-06-30 23:02:48 +03001993/*[clinic input]
1994@classmethod
1995select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001996
Tal Einat6dc57e22018-06-30 23:02:48 +03001997Kqueue syscall wrapper.
1998
1999For example, to start watching a socket for input:
2000>>> kq = kqueue()
2001>>> sock = socket()
2002>>> sock.connect((host, port))
2003>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
2004
2005To wait one second for it to become writeable:
2006>>> kq.control(None, 1, 1000)
2007
2008To stop listening:
2009>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2010[clinic start generated code]*/
2011
2012static PyObject *
2013select_kqueue_impl(PyTypeObject *type)
2014/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002017}
2018
2019static void
2020kqueue_queue_dealloc(kqueue_queue_Object *self)
2021{
Dino Viehlandf9190542019-09-14 15:20:27 +01002022 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002024 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2025 kqueue_free((PyObject *)self);
2026 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002027}
2028
Tal Einat6dc57e22018-06-30 23:02:48 +03002029/*[clinic input]
2030select.kqueue.close
2031
2032Close the kqueue control file descriptor.
2033
2034Further operations on the kqueue object will raise an exception.
2035[clinic start generated code]*/
2036
2037static PyObject *
2038select_kqueue_close_impl(kqueue_queue_Object *self)
2039/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 errno = kqueue_queue_internal_close(self);
2042 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002043 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 return NULL;
2045 }
2046 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002047}
2048
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002049static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002050kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 if (self->kqfd < 0)
2053 Py_RETURN_TRUE;
2054 else
2055 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002056}
2057
Tal Einat6dc57e22018-06-30 23:02:48 +03002058/*[clinic input]
2059select.kqueue.fileno
2060
2061Return the kqueue control file descriptor.
2062[clinic start generated code]*/
2063
2064static PyObject *
2065select_kqueue_fileno_impl(kqueue_queue_Object *self)
2066/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 if (self->kqfd < 0)
2069 return kqueue_queue_err_closed();
2070 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002071}
2072
Tal Einat6dc57e22018-06-30 23:02:48 +03002073/*[clinic input]
2074@classmethod
2075select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076
Tal Einat6dc57e22018-06-30 23:02:48 +03002077 fd: int
2078 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002079
Tal Einat6dc57e22018-06-30 23:02:48 +03002080Create a kqueue object from a given control fd.
2081[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002082
2083static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002084select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2085/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002086{
Tal Einat6dc57e22018-06-30 23:02:48 +03002087 SOCKET s_fd = (SOCKET)fd;
2088
2089 return newKqueue_Object(type, s_fd);
2090}
2091
2092/*[clinic input]
2093select.kqueue.control
2094
2095 changelist: object
2096 Must be an iterable of kevent objects describing the changes to be made
2097 to the kernel's watch list or None.
2098 maxevents: int
2099 The maximum number of events that the kernel will return.
2100 timeout as otimeout: object = None
2101 The maximum time to wait in seconds, or else None to wait forever.
2102 This accepts floats for smaller timeouts, too.
2103 /
2104
2105Calls the kernel kevent function.
2106[clinic start generated code]*/
2107
2108static PyObject *
2109select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2110 int maxevents, PyObject *otimeout)
2111/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 int gotevents = 0;
2114 int nchanges = 0;
2115 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002116 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 PyObject *result = NULL;
2118 struct kevent *evl = NULL;
2119 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002120 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002122 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 if (self->kqfd < 0)
2125 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Tal Einat6dc57e22018-06-30 23:02:48 +03002127 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 PyErr_Format(PyExc_ValueError,
2129 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002130 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 return NULL;
2132 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002133
Tal Einat6dc57e22018-06-30 23:02:48 +03002134 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 ptimeoutspec = NULL;
2136 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002137 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002138 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002139 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002140 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002141 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002142 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002143 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002144 return NULL;
2145 }
2146
Victor Stinner4448c082015-03-31 11:48:34 +02002147 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002148 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002149
Victor Stinner4448c082015-03-31 11:48:34 +02002150 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 PyErr_SetString(PyExc_ValueError,
2152 "timeout must be positive or None");
2153 return NULL;
2154 }
Victor Stinner4448c082015-03-31 11:48:34 +02002155 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002157
Tal Einat6dc57e22018-06-30 23:02:48 +03002158 if (changelist != Py_None) {
2159 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002160 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 return NULL;
2162 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002163 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2164 PyErr_SetString(PyExc_OverflowError,
2165 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 goto error;
2167 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002168 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 chl = PyMem_New(struct kevent, nchanges);
2171 if (chl == NULL) {
2172 PyErr_NoMemory();
2173 goto error;
2174 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002175 for (i = 0; i < nchanges; ++i) {
2176 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 PyErr_SetString(PyExc_TypeError,
2179 "changelist must be an iterable of "
2180 "select.kevent objects");
2181 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002183 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002185 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002189 if (maxevents) {
2190 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 if (evl == NULL) {
2192 PyErr_NoMemory();
2193 goto error;
2194 }
2195 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002196
Victor Stinner4448c082015-03-31 11:48:34 +02002197 if (ptimeoutspec)
2198 deadline = _PyTime_GetMonotonicClock() + timeout;
2199
2200 do {
2201 Py_BEGIN_ALLOW_THREADS
2202 errno = 0;
2203 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002204 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002205 Py_END_ALLOW_THREADS
2206
2207 if (errno != EINTR)
2208 break;
2209
2210 /* kevent() was interrupted by a signal */
2211 if (PyErr_CheckSignals())
2212 goto error;
2213
2214 if (ptimeoutspec) {
2215 timeout = deadline - _PyTime_GetMonotonicClock();
2216 if (timeout < 0) {
2217 gotevents = 0;
2218 break;
2219 }
2220 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2221 goto error;
2222 /* retry kevent() with the recomputed timeout */
2223 }
2224 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 if (gotevents == -1) {
2227 PyErr_SetFromErrno(PyExc_OSError);
2228 goto error;
2229 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 result = PyList_New(gotevents);
2232 if (result == NULL) {
2233 goto error;
2234 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002236 for (i = 0; i < gotevents; i++) {
2237 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002238
Dino Viehlandf9190542019-09-14 15:20:27 +01002239 ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 if (ch == NULL) {
2241 goto error;
2242 }
2243 ch->e = evl[i];
2244 PyList_SET_ITEM(result, i, (PyObject *)ch);
2245 }
2246 PyMem_Free(chl);
2247 PyMem_Free(evl);
2248 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002249
2250 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 PyMem_Free(chl);
2252 PyMem_Free(evl);
2253 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002254 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002256}
2257
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002258static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 {"closed", (getter)kqueue_queue_get_closed, NULL,
2260 "True if the kqueue handler is closed"},
2261 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262};
2263
Tal Einat6dc57e22018-06-30 23:02:48 +03002264#endif /* HAVE_KQUEUE */
2265
2266
2267/* ************************************************************************ */
2268
2269#include "clinic/selectmodule.c.h"
2270
2271#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2272
2273static PyMethodDef poll_methods[] = {
2274 SELECT_POLL_REGISTER_METHODDEF
2275 SELECT_POLL_MODIFY_METHODDEF
2276 SELECT_POLL_UNREGISTER_METHODDEF
2277 SELECT_POLL_POLL_METHODDEF
2278 {NULL, NULL} /* sentinel */
2279};
2280
Dino Viehlandf9190542019-09-14 15:20:27 +01002281
2282static PyType_Slot poll_Type_slots[] = {
2283 {Py_tp_dealloc, poll_dealloc},
2284 {Py_tp_methods, poll_methods},
2285 {Py_tp_new, poll_new},
2286 {0, 0},
2287};
2288
2289static PyType_Spec poll_Type_spec = {
2290 "select.poll",
2291 sizeof(pollObject),
2292 0,
2293 Py_TPFLAGS_DEFAULT,
2294 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002295};
2296
2297#ifdef HAVE_SYS_DEVPOLL_H
2298
2299static PyMethodDef devpoll_methods[] = {
2300 SELECT_DEVPOLL_REGISTER_METHODDEF
2301 SELECT_DEVPOLL_MODIFY_METHODDEF
2302 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2303 SELECT_DEVPOLL_POLL_METHODDEF
2304 SELECT_DEVPOLL_CLOSE_METHODDEF
2305 SELECT_DEVPOLL_FILENO_METHODDEF
2306 {NULL, NULL} /* sentinel */
2307};
2308
Tal Einat6dc57e22018-06-30 23:02:48 +03002309#endif /* HAVE_SYS_DEVPOLL_H */
2310
2311#endif /* HAVE_POLL */
2312
2313#ifdef HAVE_EPOLL
2314
2315static PyMethodDef pyepoll_methods[] = {
2316 SELECT_EPOLL_FROMFD_METHODDEF
2317 SELECT_EPOLL_CLOSE_METHODDEF
2318 SELECT_EPOLL_FILENO_METHODDEF
2319 SELECT_EPOLL_MODIFY_METHODDEF
2320 SELECT_EPOLL_REGISTER_METHODDEF
2321 SELECT_EPOLL_UNREGISTER_METHODDEF
2322 SELECT_EPOLL_POLL_METHODDEF
2323 SELECT_EPOLL___ENTER___METHODDEF
2324 SELECT_EPOLL___EXIT___METHODDEF
2325 {NULL, NULL},
2326};
2327
Dino Viehlandf9190542019-09-14 15:20:27 +01002328static PyType_Slot pyEpoll_Type_slots[] = {
2329 {Py_tp_dealloc, pyepoll_dealloc},
2330 {Py_tp_doc, (void*)pyepoll_doc},
2331 {Py_tp_getattro, PyObject_GenericGetAttr},
2332 {Py_tp_getset, pyepoll_getsetlist},
2333 {Py_tp_methods, pyepoll_methods},
2334 {Py_tp_new, select_epoll},
2335 {0, 0},
2336};
2337
2338static PyType_Spec pyEpoll_Type_spec = {
2339 "select.epoll",
2340 sizeof(pyEpoll_Object),
2341 0,
2342 Py_TPFLAGS_DEFAULT,
2343 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002344};
2345
2346#endif /* HAVE_EPOLL */
2347
2348#ifdef HAVE_KQUEUE
2349
Tal Einat6dc57e22018-06-30 23:02:48 +03002350static PyMethodDef kqueue_queue_methods[] = {
2351 SELECT_KQUEUE_FROMFD_METHODDEF
2352 SELECT_KQUEUE_CLOSE_METHODDEF
2353 SELECT_KQUEUE_FILENO_METHODDEF
2354 SELECT_KQUEUE_CONTROL_METHODDEF
2355 {NULL, NULL},
2356};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002357
Dino Viehlandf9190542019-09-14 15:20:27 +01002358static PyType_Slot kqueue_queue_Type_slots[] = {
2359 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002360 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002361 {Py_tp_getset, kqueue_queue_getsetlist},
2362 {Py_tp_methods, kqueue_queue_methods},
2363 {Py_tp_new, select_kqueue},
2364 {0, 0},
2365};
2366
2367static PyType_Spec kqueue_queue_Type_spec = {
2368 "select.kqueue",
2369 sizeof(kqueue_queue_Object),
2370 0,
2371 Py_TPFLAGS_DEFAULT,
2372 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002373};
2374
2375#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002376
2377
2378
2379
2380
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002381/* ************************************************************************ */
2382
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002383
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002384static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002385 SELECT_SELECT_METHODDEF
2386 SELECT_POLL_METHODDEF
2387 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002389};
2390
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002391PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002392"This module supports asynchronous I/O on multiple file descriptors.\n\
2393\n\
2394*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002395On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002396
Martin v. Löwis1a214512008-06-11 05:26:20 +00002397
Dino Viehlandf9190542019-09-14 15:20:27 +01002398
2399static int
2400_select_traverse(PyObject *module, visitproc visit, void *arg)
2401{
2402 Py_VISIT(_selectstate(module)->close);
2403 Py_VISIT(_selectstate(module)->poll_Type);
2404 Py_VISIT(_selectstate(module)->devpoll_Type);
2405 Py_VISIT(_selectstate(module)->pyEpoll_Type);
2406 Py_VISIT(_selectstate(module)->kqueue_event_Type);
2407 Py_VISIT(_selectstate(module)->kqueue_queue_Type);
2408 return 0;
2409}
2410
2411static int
2412_select_clear(PyObject *module)
2413{
2414 Py_CLEAR(_selectstate(module)->close);
2415 Py_CLEAR(_selectstate(module)->poll_Type);
2416 Py_CLEAR(_selectstate(module)->devpoll_Type);
2417 Py_CLEAR(_selectstate(module)->pyEpoll_Type);
2418 Py_CLEAR(_selectstate(module)->kqueue_event_Type);
2419 Py_CLEAR(_selectstate(module)->kqueue_queue_Type);
2420 return 0;
2421}
2422
2423static void
2424_select_free(void *module)
2425{
2426 _select_clear((PyObject *)module);
2427}
2428
Martin v. Löwis1a214512008-06-11 05:26:20 +00002429static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 PyModuleDef_HEAD_INIT,
2431 "select",
2432 module_doc,
Dino Viehlandf9190542019-09-14 15:20:27 +01002433 sizeof(_selectstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 select_methods,
2435 NULL,
Dino Viehlandf9190542019-09-14 15:20:27 +01002436 _select_traverse,
2437 _select_clear,
2438 _select_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002439};
2440
Mark Hammond62b1ab12002-07-23 06:31:15 +00002441PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002442PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 PyObject *m;
2445 m = PyModule_Create(&selectmodule);
2446 if (m == NULL)
2447 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002448
Dino Viehlandf9190542019-09-14 15:20:27 +01002449 _selectstate(m)->close = PyUnicode_InternFromString("close");
2450
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002451 Py_INCREF(PyExc_OSError);
2452 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002453
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002454#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002455#ifdef HAVE_BROKEN_PIPE_BUF
2456#undef PIPE_BUF
2457#define PIPE_BUF 512
2458#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002459 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002460#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002461
Charles-François Natali986a56c2013-01-19 12:19:10 +01002462#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002463#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 if (select_have_broken_poll()) {
2465 if (PyObject_DelAttrString(m, "poll") == -1) {
2466 PyErr_Clear();
2467 }
2468 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002469#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002471#endif
Dino Viehlandf9190542019-09-14 15:20:27 +01002472 PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
2473 if (poll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002475 _selectstate(m)->poll_Type = (PyTypeObject *)poll_Type;
2476 Py_INCREF(poll_Type);
2477
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002478 PyModule_AddIntMacro(m, POLLIN);
2479 PyModule_AddIntMacro(m, POLLPRI);
2480 PyModule_AddIntMacro(m, POLLOUT);
2481 PyModule_AddIntMacro(m, POLLERR);
2482 PyModule_AddIntMacro(m, POLLHUP);
2483 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002484
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002485#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002486 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002487#endif
2488#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002489 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002490#endif
2491#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002492 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002493#endif
2494#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002495 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002496#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002497#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002498 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002499#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002500#ifdef POLLRDHUP
2501 /* Kernel 2.6.17+ */
2502 PyModule_AddIntMacro(m, POLLRDHUP);
2503#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002505#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002506
Jesus Cead8b9ae62011-11-14 19:07:41 +01002507#ifdef HAVE_SYS_DEVPOLL_H
Dino Viehlandf9190542019-09-14 15:20:27 +01002508 PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
2509 if (devpoll_Type == NULL)
Jesus Cead8b9ae62011-11-14 19:07:41 +01002510 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002511 _selectstate(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
2512 Py_INCREF(devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01002513#endif
2514
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002515#ifdef HAVE_EPOLL
Dino Viehlandf9190542019-09-14 15:20:27 +01002516 PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
2517 if (pyEpoll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002519 _selectstate(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
2520 Py_INCREF(pyEpoll_Type);
2521 PyModule_AddObject(m, "epoll", (PyObject *)_selectstate(m)->pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002522
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002523 PyModule_AddIntMacro(m, EPOLLIN);
2524 PyModule_AddIntMacro(m, EPOLLOUT);
2525 PyModule_AddIntMacro(m, EPOLLPRI);
2526 PyModule_AddIntMacro(m, EPOLLERR);
2527 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002528#ifdef EPOLLRDHUP
2529 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002530 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002531#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002532 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002533#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002535 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002536#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002537#ifdef EPOLLEXCLUSIVE
2538 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2539#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002540
2541#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002542 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002543#endif
2544#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002545 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002546#endif
2547#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002548 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002549#endif
2550#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002551 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002552#endif
2553#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002554 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002555#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002556
Benjamin Peterson95c16622011-12-27 15:36:32 -06002557#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002558 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002559#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002560#endif /* HAVE_EPOLL */
2561
2562#ifdef HAVE_KQUEUE
Dino Viehlandf9190542019-09-14 15:20:27 +01002563 PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
2564 if (kqueue_event_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002566 _selectstate(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
2567 Py_INCREF(_selectstate(m)->kqueue_event_Type);
2568 PyModule_AddObject(m, "kevent", kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002569
Dino Viehlandf9190542019-09-14 15:20:27 +01002570 PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
2571 if (kqueue_queue_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002573 _selectstate(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
2574 Py_INCREF(_selectstate(m)->kqueue_queue_Type);
2575 PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002576
2577 /* event filters */
2578 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2579 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002580#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002582#endif
2583#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002585#endif
2586#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002588#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002589#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002591#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002592#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002594#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 /* event flags */
2598 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2599 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2600 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2601 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2602 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2603 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002604
Berker Peksag7ec64562016-09-14 18:16:59 +03002605#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002607#endif
2608#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002610#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2613 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002616#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002618#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002621#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2623 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2624 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2625 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2626 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2627 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2628 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002629#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002632#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2634 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2635 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2636 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2637 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2640 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2641 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002642#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643
2644 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002645#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2647 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2648 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002649#endif
2650
2651#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002653}