blob: 79cc1b265559be5ddd847d1514945db10353ed90 [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);
1450 if (errno == EBADF) {
1451 /* fd already closed */
1452 result = 0;
1453 errno = 0;
1454 }
1455 Py_END_ALLOW_THREADS
1456 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001457 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 result = -1;
1459 errno = EINVAL;
1460 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001463 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 return NULL;
1465 }
1466 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001467}
1468
Tal Einat6dc57e22018-06-30 23:02:48 +03001469/*[clinic input]
1470select.epoll.register
1471
1472 fd: fildes
1473 the target file descriptor of the operation
1474 eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = EPOLLIN | EPOLLPRI | EPOLLOUT
1475 a bit set composed of the various EPOLL constants
1476
1477Registers a new fd or raises an OSError if the fd is already registered.
1478
1479The epoll interface supports all file descriptors that support poll.
1480[clinic start generated code]*/
1481
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001482static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001483select_epoll_register_impl(pyEpoll_Object *self, int fd,
1484 unsigned int eventmask)
1485/*[clinic end generated code: output=318e5e6386520599 input=6cf699c152dd8ca9]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001486{
Tal Einat6dc57e22018-06-30 23:02:48 +03001487 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001488}
1489
Tal Einat6dc57e22018-06-30 23:02:48 +03001490/*[clinic input]
1491select.epoll.modify
1492
1493 fd: fildes
1494 the target file descriptor of the operation
1495 eventmask: unsigned_int(bitwise=True)
1496 a bit set composed of the various EPOLL constants
1497
1498Modify event mask for a registered file descriptor.
1499[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001500
1501static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001502select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1503 unsigned int eventmask)
1504/*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001505{
Tal Einat6dc57e22018-06-30 23:02:48 +03001506 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507}
1508
Tal Einat6dc57e22018-06-30 23:02:48 +03001509/*[clinic input]
1510select.epoll.unregister
1511
1512 fd: fildes
1513 the target file descriptor of the operation
1514
1515Remove a registered file descriptor from the epoll object.
1516[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001517
1518static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001519select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1520/*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001521{
Tal Einat6dc57e22018-06-30 23:02:48 +03001522 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001523}
1524
Tal Einat6dc57e22018-06-30 23:02:48 +03001525/*[clinic input]
1526select.epoll.poll
1527
1528 timeout as timeout_obj: object = None
1529 the maximum time to wait in seconds (as float);
1530 a timeout of None or -1 makes poll wait indefinitely
1531 maxevents: int = -1
1532 the maximum number of events returned; -1 means no limit
1533
1534Wait for events on the epoll file descriptor.
1535
1536Returns a list containing any descriptors that have events to report,
1537as a list of (fd, events) 2-tuples.
1538[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001539
1540static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001541select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1542 int maxevents)
1543/*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 int nfds, i;
1546 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001547 struct epoll_event *evs = NULL;
Berker Peksagb690b9b2018-09-11 20:29:48 +03001548 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 if (self->epfd < 0)
1551 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552
Berker Peksagb690b9b2018-09-11 20:29:48 +03001553 if (timeout_obj != Py_None) {
Victor Stinner41eba222015-03-30 21:59:21 +02001554 /* epoll_wait() has a resolution of 1 millisecond, round towards
1555 infinity to wait at least timeout seconds. */
1556 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001557 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001558 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1559 PyErr_SetString(PyExc_TypeError,
1560 "timeout must be an integer or None");
1561 }
1562 return NULL;
1563 }
1564
1565 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1566 if (ms < INT_MIN || ms > INT_MAX) {
1567 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1568 return NULL;
1569 }
Berker Peksagb690b9b2018-09-11 20:29:48 +03001570 /* epoll_wait(2) treats all arbitrary negative numbers the same
1571 for the timeout argument, but -1 is the documented way to block
1572 indefinitely in the epoll_wait(2) documentation, so we set ms
1573 to -1 if the value of ms is a negative number.
Victor Stinner41eba222015-03-30 21:59:21 +02001574
Berker Peksagb690b9b2018-09-11 20:29:48 +03001575 Note that we didn't use INFTIM here since it's non-standard and
1576 isn't available under Linux. */
1577 if (ms < 0) {
1578 ms = -1;
1579 }
1580
1581 if (timeout >= 0) {
1582 deadline = _PyTime_GetMonotonicClock() + timeout;
1583 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001587 maxevents = FD_SETSIZE-1;
1588 }
1589 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 PyErr_Format(PyExc_ValueError,
1591 "maxevents must be greater than 0, got %d",
1592 maxevents);
1593 return NULL;
1594 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001595
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001596 evs = PyMem_New(struct epoll_event, maxevents);
1597 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001598 PyErr_NoMemory();
1599 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Victor Stinner41eba222015-03-30 21:59:21 +02001602 do {
1603 Py_BEGIN_ALLOW_THREADS
1604 errno = 0;
1605 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1606 Py_END_ALLOW_THREADS
1607
1608 if (errno != EINTR)
1609 break;
1610
1611 /* poll() was interrupted by a signal */
1612 if (PyErr_CheckSignals())
1613 goto error;
1614
1615 if (timeout >= 0) {
1616 timeout = deadline - _PyTime_GetMonotonicClock();
1617 if (timeout < 0) {
1618 nfds = 0;
1619 break;
1620 }
1621 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1622 /* retry epoll_wait() with the recomputed timeout */
1623 }
1624 } while(1);
1625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001627 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 goto error;
1629 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 elist = PyList_New(nfds);
1632 if (elist == NULL) {
1633 goto error;
1634 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001637 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 if (etuple == NULL) {
1639 Py_CLEAR(elist);
1640 goto error;
1641 }
1642 PyList_SET_ITEM(elist, i, etuple);
1643 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001644
Christian Heimesf6cd9672008-03-26 13:45:42 +00001645 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001646 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001648}
1649
Tal Einat6dc57e22018-06-30 23:02:48 +03001650
1651/*[clinic input]
1652select.epoll.__enter__
1653
1654[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001655
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001656static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001657select_epoll___enter___impl(pyEpoll_Object *self)
1658/*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001659{
1660 if (self->epfd < 0)
1661 return pyepoll_err_closed();
1662
1663 Py_INCREF(self);
1664 return (PyObject *)self;
1665}
1666
Tal Einat6dc57e22018-06-30 23:02:48 +03001667/*[clinic input]
1668select.epoll.__exit__
1669
1670 exc_type: object = None
1671 exc_value: object = None
1672 exc_tb: object = None
1673 /
1674
1675[clinic start generated code]*/
1676
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001677static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03001678select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1679 PyObject *exc_value, PyObject *exc_tb)
1680/*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001681{
Dino Viehlandf9190542019-09-14 15:20:27 +01001682 return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL);
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001683}
1684
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001685static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 {"closed", (getter)pyepoll_get_closed, NULL,
1687 "True if the epoll handler is closed"},
1688 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001689};
1690
Dino Viehlandf9190542019-09-14 15:20:27 +01001691PyDoc_STRVAR(pyepoll_doc,
1692"select.epoll(sizehint=-1, flags=0)\n\
1693\n\
1694Returns an epolling object\n\
1695\n\
1696sizehint must be a positive integer or -1 for the default size. The\n\
1697sizehint is used to optimize internal data structures. It doesn't limit\n\
1698the maximum number of monitored events.");
1699
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001700#endif /* HAVE_EPOLL */
1701
1702#ifdef HAVE_KQUEUE
1703/* **************************************************************************
1704 * kqueue interface for BSD
1705 *
1706 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1707 * All rights reserved.
1708 *
1709 * Redistribution and use in source and binary forms, with or without
1710 * modification, are permitted provided that the following conditions
1711 * are met:
1712 * 1. Redistributions of source code must retain the above copyright
1713 * notice, this list of conditions and the following disclaimer.
1714 * 2. Redistributions in binary form must reproduce the above copyright
1715 * notice, this list of conditions and the following disclaimer in the
1716 * documentation and/or other materials provided with the distribution.
1717 *
1718 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1719 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1720 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1721 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1722 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1723 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1724 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1725 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1726 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1727 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1728 * SUCH DAMAGE.
1729 */
1730
1731#ifdef HAVE_SYS_EVENT_H
1732#include <sys/event.h>
1733#endif
1734
1735PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001736"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001737\n\
1738This object is the equivalent of the struct kevent for the C API.\n\
1739\n\
1740See the kqueue manpage for more detailed information about the meaning\n\
1741of the arguments.\n\
1742\n\
1743One minor note: while you might hope that udata could store a\n\
1744reference to a python object, it cannot, because it is impossible to\n\
1745keep a proper reference count of the object once it's passed into the\n\
1746kernel. Therefore, I have restricted it to only storing an integer. I\n\
1747recommend ignoring it and simply using the 'ident' field to key off\n\
1748of. You could also set up a dictionary on the python side to store a\n\
1749udata->object mapping.");
1750
1751typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001752 PyObject_HEAD
1753 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001754} kqueue_event_Object;
1755
Dino Viehlandf9190542019-09-14 15:20:27 +01001756#define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001757
1758typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject_HEAD
1760 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001761} kqueue_queue_Object;
1762
Dino Viehlandf9190542019-09-14 15:20:27 +01001763#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001764
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001765#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1766# error uintptr_t does not match void *!
1767#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1768# define T_UINTPTRT T_ULONGLONG
1769# define T_INTPTRT T_LONGLONG
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_LONG)
1773# define T_UINTPTRT T_ULONG
1774# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001775# define UINTPTRT_FMT_UNIT "k"
1776# define INTPTRT_FMT_UNIT "l"
1777#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1778# define T_UINTPTRT T_UINT
1779# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001780# define UINTPTRT_FMT_UNIT "I"
1781# define INTPTRT_FMT_UNIT "i"
1782#else
1783# error uintptr_t does not match int, long, or long long!
1784#endif
1785
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001786#if SIZEOF_LONG_LONG == 8
1787# define T_INT64 T_LONGLONG
1788# define INT64_FMT_UNIT "L"
1789#elif SIZEOF_LONG == 8
1790# define T_INT64 T_LONG
1791# define INT64_FMT_UNIT "l"
1792#elif SIZEOF_INT == 8
1793# define T_INT64 T_INT
1794# define INT64_FMT_UNIT "i"
1795#else
1796# define INT64_FMT_UNIT "_"
1797#endif
1798
1799#if SIZEOF_LONG_LONG == 4
1800# define T_UINT32 T_ULONGLONG
1801# define UINT32_FMT_UNIT "K"
1802#elif SIZEOF_LONG == 4
1803# define T_UINT32 T_ULONG
1804# define UINT32_FMT_UNIT "k"
1805#elif SIZEOF_INT == 4
1806# define T_UINT32 T_UINT
1807# define UINT32_FMT_UNIT "I"
1808#else
1809# define UINT32_FMT_UNIT "_"
1810#endif
1811
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001812/*
1813 * kevent is not standard and its members vary across BSDs.
1814 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001815#ifdef __NetBSD__
1816# define FILTER_TYPE T_UINT32
1817# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1818# define FLAGS_TYPE T_UINT32
1819# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1820# define FFLAGS_TYPE T_UINT32
1821# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001822#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001823# define FILTER_TYPE T_SHORT
1824# define FILTER_FMT_UNIT "h"
1825# define FLAGS_TYPE T_USHORT
1826# define FLAGS_FMT_UNIT "H"
1827# define FFLAGS_TYPE T_UINT
1828# define FFLAGS_FMT_UNIT "I"
1829#endif
1830
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001831#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001832# define DATA_TYPE T_INT64
1833# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001834#else
1835# define DATA_TYPE T_INTPTRT
1836# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001837#endif
1838
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001839/* Unfortunately, we can't store python objects in udata, because
1840 * kevents in the kernel can be removed without warning, which would
1841 * forever lose the refcount on the object stored with it.
1842 */
1843
1844#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1845static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001846 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1847 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1848 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001850 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1852 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001853};
1854#undef KQ_OFF
1855
1856static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001857
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001858kqueue_event_repr(kqueue_event_Object *s)
1859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 char buf[1024];
1861 PyOS_snprintf(
1862 buf, sizeof(buf),
1863 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001864 "data=0x%llx udata=%p>",
1865 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1866 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868}
1869
1870static int
1871kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 PyObject *pfd;
1874 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1875 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001876 static const char fmt[] = "O|"
1877 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1878 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1883 &pfd, &(self->e.filter), &(self->e.flags),
1884 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1885 return -1;
1886 }
1887
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001888 if (PyLong_Check(pfd)) {
1889 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 }
1891 else {
1892 self->e.ident = PyObject_AsFileDescriptor(pfd);
1893 }
1894 if (PyErr_Occurred()) {
1895 return -1;
1896 }
1897 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898}
1899
1900static PyObject *
1901kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001903{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001904 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001907 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001909
1910#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1911 result = CMP(s->e.ident, o->e.ident)
1912 : CMP(s->e.filter, o->e.filter)
1913 : CMP(s->e.flags, o->e.flags)
1914 : CMP(s->e.fflags, o->e.fflags)
1915 : CMP(s->e.data, o->e.data)
1916 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1917 : 0;
1918#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001919
stratakise8b19652017-11-02 11:32:54 +01001920 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001921}
1922
Dino Viehlandf9190542019-09-14 15:20:27 +01001923static PyType_Slot kqueue_event_Type_slots[] = {
1924 {Py_tp_doc, (void*)kqueue_event_doc},
1925 {Py_tp_init, kqueue_event_init},
1926 {Py_tp_members, kqueue_event_members},
1927 {Py_tp_new, PyType_GenericNew},
1928 {Py_tp_repr, kqueue_event_repr},
1929 {Py_tp_richcompare, kqueue_event_richcompare},
1930 {0, 0},
1931};
1932
1933static PyType_Spec kqueue_event_Type_spec = {
1934 "select.kevent",
1935 sizeof(kqueue_event_Object),
1936 0,
1937 Py_TPFLAGS_DEFAULT,
1938 kqueue_event_Type_slots
1939};
1940
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001941static PyObject *
1942kqueue_queue_err_closed(void)
1943{
Victor Stinner13423c32013-08-22 00:19:50 +02001944 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001946}
1947
1948static int
1949kqueue_queue_internal_close(kqueue_queue_Object *self)
1950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 int save_errno = 0;
1952 if (self->kqfd >= 0) {
1953 int kqfd = self->kqfd;
1954 self->kqfd = -1;
1955 Py_BEGIN_ALLOW_THREADS
1956 if (close(kqfd) < 0)
1957 save_errno = errno;
1958 Py_END_ALLOW_THREADS
1959 }
1960 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001961}
1962
1963static PyObject *
1964newKqueue_Object(PyTypeObject *type, SOCKET fd)
1965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 kqueue_queue_Object *self;
Dino Viehlandf9190542019-09-14 15:20:27 +01001967 assert(type != NULL);
1968 allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1969 assert(queue_alloc != NULL);
1970 self = (kqueue_queue_Object *) queue_alloc(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 if (self == NULL) {
1972 return NULL;
1973 }
1974
1975 if (fd == -1) {
1976 Py_BEGIN_ALLOW_THREADS
1977 self->kqfd = kqueue();
1978 Py_END_ALLOW_THREADS
1979 }
1980 else {
1981 self->kqfd = fd;
1982 }
1983 if (self->kqfd < 0) {
1984 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001985 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 return NULL;
1987 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001988
1989 if (fd == -1) {
1990 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1991 Py_DECREF(self);
1992 return NULL;
1993 }
1994 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001996}
1997
Tal Einat6dc57e22018-06-30 23:02:48 +03001998/*[clinic input]
1999@classmethod
2000select.kqueue.__new__
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002001
Tal Einat6dc57e22018-06-30 23:02:48 +03002002Kqueue syscall wrapper.
2003
2004For example, to start watching a socket for input:
2005>>> kq = kqueue()
2006>>> sock = socket()
2007>>> sock.connect((host, port))
2008>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
2009
2010To wait one second for it to become writeable:
2011>>> kq.control(None, 1, 1000)
2012
2013To stop listening:
2014>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2015[clinic start generated code]*/
2016
2017static PyObject *
2018select_kqueue_impl(PyTypeObject *type)
2019/*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002022}
2023
2024static void
2025kqueue_queue_dealloc(kqueue_queue_Object *self)
2026{
Dino Viehlandf9190542019-09-14 15:20:27 +01002027 PyTypeObject* type = Py_TYPE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 kqueue_queue_internal_close(self);
Dino Viehlandf9190542019-09-14 15:20:27 +01002029 freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2030 kqueue_free((PyObject *)self);
2031 Py_DECREF((PyObject *)type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002032}
2033
Tal Einat6dc57e22018-06-30 23:02:48 +03002034/*[clinic input]
2035select.kqueue.close
2036
2037Close the kqueue control file descriptor.
2038
2039Further operations on the kqueue object will raise an exception.
2040[clinic start generated code]*/
2041
2042static PyObject *
2043select_kqueue_close_impl(kqueue_queue_Object *self)
2044/*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 errno = kqueue_queue_internal_close(self);
2047 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002048 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 return NULL;
2050 }
2051 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002052}
2053
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002054static PyObject*
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002055kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002056{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 if (self->kqfd < 0)
2058 Py_RETURN_TRUE;
2059 else
2060 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002061}
2062
Tal Einat6dc57e22018-06-30 23:02:48 +03002063/*[clinic input]
2064select.kqueue.fileno
2065
2066Return the kqueue control file descriptor.
2067[clinic start generated code]*/
2068
2069static PyObject *
2070select_kqueue_fileno_impl(kqueue_queue_Object *self)
2071/*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 if (self->kqfd < 0)
2074 return kqueue_queue_err_closed();
2075 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076}
2077
Tal Einat6dc57e22018-06-30 23:02:48 +03002078/*[clinic input]
2079@classmethod
2080select.kqueue.fromfd
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002081
Tal Einat6dc57e22018-06-30 23:02:48 +03002082 fd: int
2083 /
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002084
Tal Einat6dc57e22018-06-30 23:02:48 +03002085Create a kqueue object from a given control fd.
2086[clinic start generated code]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002087
2088static PyObject *
Tal Einat6dc57e22018-06-30 23:02:48 +03002089select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2090/*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002091{
Tal Einat6dc57e22018-06-30 23:02:48 +03002092 SOCKET s_fd = (SOCKET)fd;
2093
2094 return newKqueue_Object(type, s_fd);
2095}
2096
2097/*[clinic input]
2098select.kqueue.control
2099
2100 changelist: object
2101 Must be an iterable of kevent objects describing the changes to be made
2102 to the kernel's watch list or None.
2103 maxevents: int
2104 The maximum number of events that the kernel will return.
2105 timeout as otimeout: object = None
2106 The maximum time to wait in seconds, or else None to wait forever.
2107 This accepts floats for smaller timeouts, too.
2108 /
2109
2110Calls the kernel kevent function.
2111[clinic start generated code]*/
2112
2113static PyObject *
2114select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2115 int maxevents, PyObject *otimeout)
2116/*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 int gotevents = 0;
2119 int nchanges = 0;
2120 int i = 0;
Serhiy Storchakade072102017-10-12 22:17:46 +03002121 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 PyObject *result = NULL;
2123 struct kevent *evl = NULL;
2124 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002125 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002127 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 if (self->kqfd < 0)
2130 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002131
Tal Einat6dc57e22018-06-30 23:02:48 +03002132 if (maxevents < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 PyErr_Format(PyExc_ValueError,
2134 "Length of eventlist must be 0 or positive, got %d",
Tal Einat6dc57e22018-06-30 23:02:48 +03002135 maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 return NULL;
2137 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002138
Tal Einat6dc57e22018-06-30 23:02:48 +03002139 if (otimeout == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 ptimeoutspec = NULL;
2141 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002142 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002143 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002144 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002145 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002146 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002147 "or None, got %.200s",
Dino Viehlandf9190542019-09-14 15:20:27 +01002148 _PyType_Name(Py_TYPE(otimeout)));
Victor Stinnerc3378382015-03-28 05:07:51 +01002149 return NULL;
2150 }
2151
Victor Stinner4448c082015-03-31 11:48:34 +02002152 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002153 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002154
Victor Stinner4448c082015-03-31 11:48:34 +02002155 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 PyErr_SetString(PyExc_ValueError,
2157 "timeout must be positive or None");
2158 return NULL;
2159 }
Victor Stinner4448c082015-03-31 11:48:34 +02002160 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002162
Tal Einat6dc57e22018-06-30 23:02:48 +03002163 if (changelist != Py_None) {
2164 seq = PySequence_Fast(changelist, "changelist is not iterable");
Serhiy Storchakade072102017-10-12 22:17:46 +03002165 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 return NULL;
2167 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002168 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2169 PyErr_SetString(PyExc_OverflowError,
2170 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 goto error;
2172 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002173 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 chl = PyMem_New(struct kevent, nchanges);
2176 if (chl == NULL) {
2177 PyErr_NoMemory();
2178 goto error;
2179 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002180 for (i = 0; i < nchanges; ++i) {
2181 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 PyErr_SetString(PyExc_TypeError,
2184 "changelist must be an iterable of "
2185 "select.kevent objects");
2186 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002188 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002190 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 /* event list */
Tal Einat6dc57e22018-06-30 23:02:48 +03002194 if (maxevents) {
2195 evl = PyMem_New(struct kevent, maxevents);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 if (evl == NULL) {
2197 PyErr_NoMemory();
2198 goto error;
2199 }
2200 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002201
Victor Stinner4448c082015-03-31 11:48:34 +02002202 if (ptimeoutspec)
2203 deadline = _PyTime_GetMonotonicClock() + timeout;
2204
2205 do {
2206 Py_BEGIN_ALLOW_THREADS
2207 errno = 0;
2208 gotevents = kevent(self->kqfd, chl, nchanges,
Tal Einat6dc57e22018-06-30 23:02:48 +03002209 evl, maxevents, ptimeoutspec);
Victor Stinner4448c082015-03-31 11:48:34 +02002210 Py_END_ALLOW_THREADS
2211
2212 if (errno != EINTR)
2213 break;
2214
2215 /* kevent() was interrupted by a signal */
2216 if (PyErr_CheckSignals())
2217 goto error;
2218
2219 if (ptimeoutspec) {
2220 timeout = deadline - _PyTime_GetMonotonicClock();
2221 if (timeout < 0) {
2222 gotevents = 0;
2223 break;
2224 }
2225 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2226 goto error;
2227 /* retry kevent() with the recomputed timeout */
2228 }
2229 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 if (gotevents == -1) {
2232 PyErr_SetFromErrno(PyExc_OSError);
2233 goto error;
2234 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002236 result = PyList_New(gotevents);
2237 if (result == NULL) {
2238 goto error;
2239 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 for (i = 0; i < gotevents; i++) {
2242 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002243
Dino Viehlandf9190542019-09-14 15:20:27 +01002244 ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 if (ch == NULL) {
2246 goto error;
2247 }
2248 ch->e = evl[i];
2249 PyList_SET_ITEM(result, i, (PyObject *)ch);
2250 }
2251 PyMem_Free(chl);
2252 PyMem_Free(evl);
2253 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002254
2255 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 PyMem_Free(chl);
2257 PyMem_Free(evl);
2258 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002259 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002261}
2262
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002263static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 {"closed", (getter)kqueue_queue_get_closed, NULL,
2265 "True if the kqueue handler is closed"},
2266 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002267};
2268
Tal Einat6dc57e22018-06-30 23:02:48 +03002269#endif /* HAVE_KQUEUE */
2270
2271
2272/* ************************************************************************ */
2273
2274#include "clinic/selectmodule.c.h"
2275
2276#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2277
2278static PyMethodDef poll_methods[] = {
2279 SELECT_POLL_REGISTER_METHODDEF
2280 SELECT_POLL_MODIFY_METHODDEF
2281 SELECT_POLL_UNREGISTER_METHODDEF
2282 SELECT_POLL_POLL_METHODDEF
2283 {NULL, NULL} /* sentinel */
2284};
2285
Dino Viehlandf9190542019-09-14 15:20:27 +01002286
2287static PyType_Slot poll_Type_slots[] = {
2288 {Py_tp_dealloc, poll_dealloc},
2289 {Py_tp_methods, poll_methods},
2290 {Py_tp_new, poll_new},
2291 {0, 0},
2292};
2293
2294static PyType_Spec poll_Type_spec = {
2295 "select.poll",
2296 sizeof(pollObject),
2297 0,
2298 Py_TPFLAGS_DEFAULT,
2299 poll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002300};
2301
2302#ifdef HAVE_SYS_DEVPOLL_H
2303
2304static PyMethodDef devpoll_methods[] = {
2305 SELECT_DEVPOLL_REGISTER_METHODDEF
2306 SELECT_DEVPOLL_MODIFY_METHODDEF
2307 SELECT_DEVPOLL_UNREGISTER_METHODDEF
2308 SELECT_DEVPOLL_POLL_METHODDEF
2309 SELECT_DEVPOLL_CLOSE_METHODDEF
2310 SELECT_DEVPOLL_FILENO_METHODDEF
2311 {NULL, NULL} /* sentinel */
2312};
2313
Tal Einat6dc57e22018-06-30 23:02:48 +03002314#endif /* HAVE_SYS_DEVPOLL_H */
2315
2316#endif /* HAVE_POLL */
2317
2318#ifdef HAVE_EPOLL
2319
2320static PyMethodDef pyepoll_methods[] = {
2321 SELECT_EPOLL_FROMFD_METHODDEF
2322 SELECT_EPOLL_CLOSE_METHODDEF
2323 SELECT_EPOLL_FILENO_METHODDEF
2324 SELECT_EPOLL_MODIFY_METHODDEF
2325 SELECT_EPOLL_REGISTER_METHODDEF
2326 SELECT_EPOLL_UNREGISTER_METHODDEF
2327 SELECT_EPOLL_POLL_METHODDEF
2328 SELECT_EPOLL___ENTER___METHODDEF
2329 SELECT_EPOLL___EXIT___METHODDEF
2330 {NULL, NULL},
2331};
2332
Dino Viehlandf9190542019-09-14 15:20:27 +01002333static PyType_Slot pyEpoll_Type_slots[] = {
2334 {Py_tp_dealloc, pyepoll_dealloc},
2335 {Py_tp_doc, (void*)pyepoll_doc},
2336 {Py_tp_getattro, PyObject_GenericGetAttr},
2337 {Py_tp_getset, pyepoll_getsetlist},
2338 {Py_tp_methods, pyepoll_methods},
2339 {Py_tp_new, select_epoll},
2340 {0, 0},
2341};
2342
2343static PyType_Spec pyEpoll_Type_spec = {
2344 "select.epoll",
2345 sizeof(pyEpoll_Object),
2346 0,
2347 Py_TPFLAGS_DEFAULT,
2348 pyEpoll_Type_slots
Tal Einat6dc57e22018-06-30 23:02:48 +03002349};
2350
2351#endif /* HAVE_EPOLL */
2352
2353#ifdef HAVE_KQUEUE
2354
Tal Einat6dc57e22018-06-30 23:02:48 +03002355static PyMethodDef kqueue_queue_methods[] = {
2356 SELECT_KQUEUE_FROMFD_METHODDEF
2357 SELECT_KQUEUE_CLOSE_METHODDEF
2358 SELECT_KQUEUE_FILENO_METHODDEF
2359 SELECT_KQUEUE_CONTROL_METHODDEF
2360 {NULL, NULL},
2361};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002362
Dino Viehlandf9190542019-09-14 15:20:27 +01002363static PyType_Slot kqueue_queue_Type_slots[] = {
2364 {Py_tp_dealloc, kqueue_queue_dealloc},
Xiang Zhang303475e2019-10-07 20:01:54 +08002365 {Py_tp_doc, (void*)select_kqueue__doc__},
Dino Viehlandf9190542019-09-14 15:20:27 +01002366 {Py_tp_getset, kqueue_queue_getsetlist},
2367 {Py_tp_methods, kqueue_queue_methods},
2368 {Py_tp_new, select_kqueue},
2369 {0, 0},
2370};
2371
2372static PyType_Spec kqueue_queue_Type_spec = {
2373 "select.kqueue",
2374 sizeof(kqueue_queue_Object),
2375 0,
2376 Py_TPFLAGS_DEFAULT,
2377 kqueue_queue_Type_slots
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002378};
2379
2380#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002381
2382
2383
2384
2385
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002386/* ************************************************************************ */
2387
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002388
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002389static PyMethodDef select_methods[] = {
Tal Einat6dc57e22018-06-30 23:02:48 +03002390 SELECT_SELECT_METHODDEF
2391 SELECT_POLL_METHODDEF
2392 SELECT_DEVPOLL_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002394};
2395
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002396PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002397"This module supports asynchronous I/O on multiple file descriptors.\n\
2398\n\
2399*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002400On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002401
Martin v. Löwis1a214512008-06-11 05:26:20 +00002402
Dino Viehlandf9190542019-09-14 15:20:27 +01002403
2404static int
2405_select_traverse(PyObject *module, visitproc visit, void *arg)
2406{
2407 Py_VISIT(_selectstate(module)->close);
2408 Py_VISIT(_selectstate(module)->poll_Type);
2409 Py_VISIT(_selectstate(module)->devpoll_Type);
2410 Py_VISIT(_selectstate(module)->pyEpoll_Type);
2411 Py_VISIT(_selectstate(module)->kqueue_event_Type);
2412 Py_VISIT(_selectstate(module)->kqueue_queue_Type);
2413 return 0;
2414}
2415
2416static int
2417_select_clear(PyObject *module)
2418{
2419 Py_CLEAR(_selectstate(module)->close);
2420 Py_CLEAR(_selectstate(module)->poll_Type);
2421 Py_CLEAR(_selectstate(module)->devpoll_Type);
2422 Py_CLEAR(_selectstate(module)->pyEpoll_Type);
2423 Py_CLEAR(_selectstate(module)->kqueue_event_Type);
2424 Py_CLEAR(_selectstate(module)->kqueue_queue_Type);
2425 return 0;
2426}
2427
2428static void
2429_select_free(void *module)
2430{
2431 _select_clear((PyObject *)module);
2432}
2433
Martin v. Löwis1a214512008-06-11 05:26:20 +00002434static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 PyModuleDef_HEAD_INIT,
2436 "select",
2437 module_doc,
Dino Viehlandf9190542019-09-14 15:20:27 +01002438 sizeof(_selectstate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 select_methods,
2440 NULL,
Dino Viehlandf9190542019-09-14 15:20:27 +01002441 _select_traverse,
2442 _select_clear,
2443 _select_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002444};
2445
Mark Hammond62b1ab12002-07-23 06:31:15 +00002446PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002447PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449 PyObject *m;
2450 m = PyModule_Create(&selectmodule);
2451 if (m == NULL)
2452 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002453
Dino Viehlandf9190542019-09-14 15:20:27 +01002454 _selectstate(m)->close = PyUnicode_InternFromString("close");
2455
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002456 Py_INCREF(PyExc_OSError);
2457 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002458
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002459#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002460#ifdef HAVE_BROKEN_PIPE_BUF
2461#undef PIPE_BUF
2462#define PIPE_BUF 512
2463#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002464 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002465#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002466
Charles-François Natali986a56c2013-01-19 12:19:10 +01002467#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002468#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 if (select_have_broken_poll()) {
2470 if (PyObject_DelAttrString(m, "poll") == -1) {
2471 PyErr_Clear();
2472 }
2473 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002474#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002476#endif
Dino Viehlandf9190542019-09-14 15:20:27 +01002477 PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec);
2478 if (poll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002480 _selectstate(m)->poll_Type = (PyTypeObject *)poll_Type;
2481 Py_INCREF(poll_Type);
2482
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002483 PyModule_AddIntMacro(m, POLLIN);
2484 PyModule_AddIntMacro(m, POLLPRI);
2485 PyModule_AddIntMacro(m, POLLOUT);
2486 PyModule_AddIntMacro(m, POLLERR);
2487 PyModule_AddIntMacro(m, POLLHUP);
2488 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002489
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002490#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002491 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002492#endif
2493#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002494 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002495#endif
2496#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002497 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002498#endif
2499#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002500 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002501#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002502#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002503 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002504#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002505#ifdef POLLRDHUP
2506 /* Kernel 2.6.17+ */
2507 PyModule_AddIntMacro(m, POLLRDHUP);
2508#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002510#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002511
Jesus Cead8b9ae62011-11-14 19:07:41 +01002512#ifdef HAVE_SYS_DEVPOLL_H
Dino Viehlandf9190542019-09-14 15:20:27 +01002513 PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec);
2514 if (devpoll_Type == NULL)
Jesus Cead8b9ae62011-11-14 19:07:41 +01002515 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002516 _selectstate(m)->devpoll_Type = (PyTypeObject *)devpoll_Type;
2517 Py_INCREF(devpoll_Type);
Jesus Cead8b9ae62011-11-14 19:07:41 +01002518#endif
2519
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002520#ifdef HAVE_EPOLL
Dino Viehlandf9190542019-09-14 15:20:27 +01002521 PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec);
2522 if (pyEpoll_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002524 _selectstate(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type;
2525 Py_INCREF(pyEpoll_Type);
2526 PyModule_AddObject(m, "epoll", (PyObject *)_selectstate(m)->pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002527
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002528 PyModule_AddIntMacro(m, EPOLLIN);
2529 PyModule_AddIntMacro(m, EPOLLOUT);
2530 PyModule_AddIntMacro(m, EPOLLPRI);
2531 PyModule_AddIntMacro(m, EPOLLERR);
2532 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002533#ifdef EPOLLRDHUP
2534 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002535 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002536#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002537 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002538#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002540 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002541#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002542#ifdef EPOLLEXCLUSIVE
2543 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2544#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002545
2546#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002547 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002548#endif
2549#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002550 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002551#endif
2552#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002553 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002554#endif
2555#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002556 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002557#endif
2558#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002559 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002560#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002561
Benjamin Peterson95c16622011-12-27 15:36:32 -06002562#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002563 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002564#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002565#endif /* HAVE_EPOLL */
2566
2567#ifdef HAVE_KQUEUE
Dino Viehlandf9190542019-09-14 15:20:27 +01002568 PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec);
2569 if (kqueue_event_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002571 _selectstate(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type;
2572 Py_INCREF(_selectstate(m)->kqueue_event_Type);
2573 PyModule_AddObject(m, "kevent", kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002574
Dino Viehlandf9190542019-09-14 15:20:27 +01002575 PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec);
2576 if (kqueue_queue_Type == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 return NULL;
Dino Viehlandf9190542019-09-14 15:20:27 +01002578 _selectstate(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type;
2579 Py_INCREF(_selectstate(m)->kqueue_queue_Type);
2580 PyModule_AddObject(m, "kqueue", kqueue_queue_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581
2582 /* event filters */
2583 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2584 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002585#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#endif
2588#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002590#endif
2591#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002592 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002593#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002594#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002597#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002599#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 /* event flags */
2603 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2604 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2605 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2606 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2607 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2608 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002609
Berker Peksag7ec64562016-09-14 18:16:59 +03002610#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002612#endif
2613#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002615#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2618 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002621#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002623#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002626#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2628 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2629 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2630 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2631 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2632 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2633 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002634#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002637#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002638 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2639 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2640 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2641 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2642 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2645 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2646 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002647#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002648
2649 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002650#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2652 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2653 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002654#endif
2655
2656#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002658}