Branch data Line data Source code
1 : : /* select - Module containing unix select(2) call.
2 : : 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.
5 : : */
6 : :
7 : : #ifndef Py_BUILD_CORE_BUILTIN
8 : : # define Py_BUILD_CORE_MODULE 1
9 : : #endif
10 : :
11 : : #if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
12 : : # define _GNU_SOURCE
13 : : #endif
14 : :
15 : : #include "Python.h"
16 : : #include "pycore_fileutils.h" // _Py_set_inheritable()
17 : : #include "structmember.h" // PyMemberDef
18 : :
19 : : #ifdef HAVE_SYS_DEVPOLL_H
20 : : #include <sys/resource.h>
21 : : #include <sys/devpoll.h>
22 : : #include <sys/types.h>
23 : : #include <sys/stat.h>
24 : : #include <fcntl.h>
25 : : #endif
26 : :
27 : : #ifdef __APPLE__
28 : : /* Perform runtime testing for a broken poll on OSX to make it easier
29 : : * to use the same binary on multiple releases of the OS.
30 : : */
31 : : #undef HAVE_BROKEN_POLL
32 : : #endif
33 : :
34 : : /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
35 : : 64 is too small (too many people have bumped into that limit).
36 : : Here we boost it.
37 : : Users who want even more than the boosted limit should #define
38 : : FD_SETSIZE higher before this; e.g., via compiler /D switch.
39 : : */
40 : : #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
41 : : #define FD_SETSIZE 512
42 : : #endif
43 : :
44 : : #if defined(HAVE_POLL_H)
45 : : #include <poll.h>
46 : : #elif defined(HAVE_SYS_POLL_H)
47 : : #include <sys/poll.h>
48 : : #endif
49 : :
50 : : #ifdef __sgi
51 : : /* This is missing from unistd.h */
52 : : extern void bzero(void *, int);
53 : : #endif
54 : :
55 : : #ifdef HAVE_SYS_TYPES_H
56 : : #include <sys/types.h>
57 : : #endif
58 : :
59 : : #ifdef MS_WINDOWS
60 : : # ifndef WIN32_LEAN_AND_MEAN
61 : : # define WIN32_LEAN_AND_MEAN
62 : : # endif
63 : : # include <winsock2.h>
64 : : #else
65 : : # define SOCKET int
66 : : #endif
67 : :
68 : : // WASI SDK 16 does not have POLLPRIO, define as no-op
69 : : #if defined(__wasi__) && !defined(POLLPRI)
70 : : # define POLLPRI 0
71 : : #endif
72 : :
73 : : typedef struct {
74 : : PyObject *close;
75 : : PyTypeObject *poll_Type;
76 : : PyTypeObject *devpoll_Type;
77 : : PyTypeObject *pyEpoll_Type;
78 : : PyTypeObject *kqueue_event_Type;
79 : : PyTypeObject *kqueue_queue_Type;
80 : : } _selectstate;
81 : :
82 : : static struct PyModuleDef selectmodule;
83 : :
84 : : static inline _selectstate*
85 : 22 : get_select_state(PyObject *module)
86 : : {
87 : 22 : void *state = PyModule_GetState(module);
88 : : assert(state != NULL);
89 : 22 : return (_selectstate *)state;
90 : : }
91 : :
92 : : #define _selectstate_by_type(type) get_select_state(PyType_GetModule(type))
93 : :
94 : : /*[clinic input]
95 : : module select
96 : : class select.poll "pollObject *" "_selectstate_by_type(type)->poll_Type"
97 : : class select.devpoll "devpollObject *" "_selectstate_by_type(type)->devpoll_Type"
98 : : class select.epoll "pyEpoll_Object *" "_selectstate_by_type(type)->pyEpoll_Type"
99 : : class select.kqueue "kqueue_queue_Object *" "_selectstate_by_type(type)->kqueue_queue_Type"
100 : : [clinic start generated code]*/
101 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8072de35824aa327]*/
102 : :
103 : : /* list of Python objects and their file descriptor */
104 : : typedef struct {
105 : : PyObject *obj; /* owned reference */
106 : : SOCKET fd;
107 : : int sentinel; /* -1 == sentinel */
108 : : } pylist;
109 : :
110 : : static void
111 : 0 : reap_obj(pylist fd2obj[FD_SETSIZE + 1])
112 : : {
113 : : unsigned int i;
114 [ # # # # ]: 0 : for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
115 [ # # ]: 0 : Py_CLEAR(fd2obj[i].obj);
116 : : }
117 : 0 : fd2obj[0].sentinel = -1;
118 : 0 : }
119 : :
120 : :
121 : : /* returns -1 and sets the Python exception if an error occurred, otherwise
122 : : returns a number >= 0
123 : : */
124 : : static int
125 : 0 : seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
126 : : {
127 : 0 : int max = -1;
128 : 0 : unsigned int index = 0;
129 : : Py_ssize_t i;
130 : 0 : PyObject* fast_seq = NULL;
131 : 0 : PyObject* o = NULL;
132 : :
133 : 0 : fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
134 : 0 : FD_ZERO(set);
135 : :
136 : 0 : fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
137 [ # # ]: 0 : if (!fast_seq)
138 : 0 : return -1;
139 : :
140 [ # # # # ]: 0 : for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
141 : : SOCKET v;
142 : :
143 : : /* any intervening fileno() calls could decr this refcnt */
144 [ # # # # ]: 0 : if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
145 : 0 : goto finally;
146 : :
147 : 0 : Py_INCREF(o);
148 : 0 : v = PyObject_AsFileDescriptor( o );
149 [ # # ]: 0 : if (v == -1) goto finally;
150 : :
151 : : #if defined(_MSC_VER)
152 : : max = 0; /* not used for Win32 */
153 : : #else /* !_MSC_VER */
154 [ # # ]: 0 : if (!_PyIsSelectable_fd(v)) {
155 : 0 : PyErr_SetString(PyExc_ValueError,
156 : : "filedescriptor out of range in select()");
157 : 0 : goto finally;
158 : : }
159 [ # # ]: 0 : if (v > max)
160 : 0 : max = v;
161 : : #endif /* _MSC_VER */
162 : 0 : FD_SET(v, set);
163 : :
164 : : /* add object and its file descriptor to the list */
165 [ # # ]: 0 : if (index >= (unsigned int)FD_SETSIZE) {
166 : 0 : PyErr_SetString(PyExc_ValueError,
167 : : "too many file descriptors in select()");
168 : 0 : goto finally;
169 : : }
170 : 0 : fd2obj[index].obj = o;
171 : 0 : fd2obj[index].fd = v;
172 : 0 : fd2obj[index].sentinel = 0;
173 : 0 : fd2obj[++index].sentinel = -1;
174 : : }
175 : 0 : Py_DECREF(fast_seq);
176 : 0 : return max+1;
177 : :
178 : 0 : finally:
179 : 0 : Py_XDECREF(o);
180 : 0 : Py_DECREF(fast_seq);
181 : 0 : return -1;
182 : : }
183 : :
184 : : /* returns NULL and sets the Python exception if an error occurred */
185 : : static PyObject *
186 : 0 : set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
187 : : {
188 : 0 : int i, j, count=0;
189 : : PyObject *list, *o;
190 : : SOCKET fd;
191 : :
192 [ # # ]: 0 : for (j = 0; fd2obj[j].sentinel >= 0; j++) {
193 [ # # ]: 0 : if (FD_ISSET(fd2obj[j].fd, set))
194 : 0 : count++;
195 : : }
196 : 0 : list = PyList_New(count);
197 [ # # ]: 0 : if (!list)
198 : 0 : return NULL;
199 : :
200 : 0 : i = 0;
201 [ # # ]: 0 : for (j = 0; fd2obj[j].sentinel >= 0; j++) {
202 : 0 : fd = fd2obj[j].fd;
203 [ # # ]: 0 : if (FD_ISSET(fd, set)) {
204 : 0 : o = fd2obj[j].obj;
205 : 0 : fd2obj[j].obj = NULL;
206 : : /* transfer ownership */
207 [ # # ]: 0 : if (PyList_SetItem(list, i, o) < 0)
208 : 0 : goto finally;
209 : :
210 : 0 : i++;
211 : : }
212 : : }
213 : 0 : return list;
214 : 0 : finally:
215 : 0 : Py_DECREF(list);
216 : 0 : return NULL;
217 : : }
218 : :
219 : : #undef SELECT_USES_HEAP
220 : : #if FD_SETSIZE > 1024
221 : : #define SELECT_USES_HEAP
222 : : #endif /* FD_SETSIZE > 1024 */
223 : :
224 : : /*[clinic input]
225 : : select.select
226 : :
227 : : rlist: object
228 : : wlist: object
229 : : xlist: object
230 : : timeout as timeout_obj: object = None
231 : : /
232 : :
233 : : Wait until one or more file descriptors are ready for some kind of I/O.
234 : :
235 : : The first three arguments are iterables of file descriptors to be waited for:
236 : : rlist -- wait until ready for reading
237 : : wlist -- wait until ready for writing
238 : : xlist -- wait for an "exceptional condition"
239 : : If only one kind of condition is required, pass [] for the other lists.
240 : :
241 : : A file descriptor is either a socket or file object, or a small integer
242 : : gotten from a fileno() method call on one of those.
243 : :
244 : : The optional 4th argument specifies a timeout in seconds; it may be
245 : : a floating point number to specify fractions of seconds. If it is absent
246 : : or None, the call will never time out.
247 : :
248 : : The return value is a tuple of three lists corresponding to the first three
249 : : arguments; each contains the subset of the corresponding file descriptors
250 : : that are ready.
251 : :
252 : : *** IMPORTANT NOTICE ***
253 : : On Windows, only sockets are supported; on Unix, all file
254 : : descriptors can be used.
255 : : [clinic start generated code]*/
256 : :
257 : : static PyObject *
258 : 0 : select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
259 : : PyObject *xlist, PyObject *timeout_obj)
260 : : /*[clinic end generated code: output=2b3cfa824f7ae4cf input=e467f5d68033de00]*/
261 : : {
262 : : #ifdef SELECT_USES_HEAP
263 : : pylist *rfd2obj, *wfd2obj, *efd2obj;
264 : : #else /* !SELECT_USES_HEAP */
265 : : /* 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];
274 : : #endif /* SELECT_USES_HEAP */
275 : 0 : PyObject *ret = NULL;
276 : : fd_set ifdset, ofdset, efdset;
277 : : struct timeval tv, *tvp;
278 : : int imax, omax, emax, max;
279 : : int n;
280 : 0 : _PyTime_t timeout, deadline = 0;
281 : :
282 [ # # ]: 0 : if (timeout_obj == Py_None)
283 : 0 : tvp = (struct timeval *)NULL;
284 : : else {
285 [ # # ]: 0 : if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
286 : : _PyTime_ROUND_TIMEOUT) < 0) {
287 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
288 : 0 : PyErr_SetString(PyExc_TypeError,
289 : : "timeout must be a float or None");
290 : : }
291 : 0 : return NULL;
292 : : }
293 : :
294 [ # # ]: 0 : if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
295 : 0 : return NULL;
296 [ # # ]: 0 : if (tv.tv_sec < 0) {
297 : 0 : PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
298 : 0 : return NULL;
299 : : }
300 : 0 : tvp = &tv;
301 : : }
302 : :
303 : : #ifdef SELECT_USES_HEAP
304 : : /* 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_Free(rfd2obj);
310 : : if (wfd2obj) PyMem_Free(wfd2obj);
311 : : if (efd2obj) PyMem_Free(efd2obj);
312 : : return PyErr_NoMemory();
313 : : }
314 : : #endif /* SELECT_USES_HEAP */
315 : :
316 : : /* Convert iterables to fd_sets, and get maximum fd number
317 : : * propagates the Python exception set in seq2set()
318 : : */
319 : 0 : rfd2obj[0].sentinel = -1;
320 : 0 : wfd2obj[0].sentinel = -1;
321 : 0 : efd2obj[0].sentinel = -1;
322 [ # # ]: 0 : if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0)
323 : 0 : goto finally;
324 [ # # ]: 0 : if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0)
325 : 0 : goto finally;
326 [ # # ]: 0 : if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0)
327 : 0 : goto finally;
328 : :
329 : 0 : max = imax;
330 [ # # ]: 0 : if (omax > max) max = omax;
331 [ # # ]: 0 : if (emax > max) max = emax;
332 : :
333 [ # # ]: 0 : if (tvp) {
334 : 0 : deadline = _PyDeadline_Init(timeout);
335 : : }
336 : :
337 : : do {
338 : 0 : Py_BEGIN_ALLOW_THREADS
339 : 0 : errno = 0;
340 [ # # # # : 0 : n = select(
# # ]
341 : : max,
342 : : imax ? &ifdset : NULL,
343 : : omax ? &ofdset : NULL,
344 : : emax ? &efdset : NULL,
345 : : tvp);
346 : 0 : Py_END_ALLOW_THREADS
347 : :
348 [ # # ]: 0 : if (errno != EINTR)
349 : 0 : break;
350 : :
351 : : /* select() was interrupted by a signal */
352 [ # # ]: 0 : if (PyErr_CheckSignals())
353 : 0 : goto finally;
354 : :
355 [ # # ]: 0 : if (tvp) {
356 : 0 : timeout = _PyDeadline_Get(deadline);
357 [ # # ]: 0 : if (timeout < 0) {
358 : : /* bpo-35310: lists were unmodified -- clear them explicitly */
359 : 0 : FD_ZERO(&ifdset);
360 : 0 : FD_ZERO(&ofdset);
361 : 0 : FD_ZERO(&efdset);
362 : 0 : n = 0;
363 : 0 : break;
364 : : }
365 : 0 : _PyTime_AsTimeval_clamp(timeout, &tv, _PyTime_ROUND_CEILING);
366 : : /* retry select() with the recomputed timeout */
367 : : }
368 : : } while (1);
369 : :
370 : : #ifdef MS_WINDOWS
371 : : if (n == SOCKET_ERROR) {
372 : : PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
373 : : }
374 : : #else
375 [ # # ]: 0 : if (n < 0) {
376 : 0 : PyErr_SetFromErrno(PyExc_OSError);
377 : : }
378 : : #endif
379 : : else {
380 : : /* any of these three calls can raise an exception. it's more
381 : : convenient to test for this after all three calls... but
382 : : is that acceptable?
383 : : */
384 : 0 : rlist = set2list(&ifdset, rfd2obj);
385 : 0 : wlist = set2list(&ofdset, wfd2obj);
386 : 0 : xlist = set2list(&efdset, efd2obj);
387 [ # # ]: 0 : if (PyErr_Occurred())
388 : 0 : ret = NULL;
389 : : else
390 : 0 : ret = PyTuple_Pack(3, rlist, wlist, xlist);
391 : :
392 : 0 : Py_XDECREF(rlist);
393 : 0 : Py_XDECREF(wlist);
394 : 0 : Py_XDECREF(xlist);
395 : : }
396 : :
397 : 0 : finally:
398 : 0 : reap_obj(rfd2obj);
399 : 0 : reap_obj(wfd2obj);
400 : 0 : reap_obj(efd2obj);
401 : : #ifdef SELECT_USES_HEAP
402 : : PyMem_Free(rfd2obj);
403 : : PyMem_Free(wfd2obj);
404 : : PyMem_Free(efd2obj);
405 : : #endif /* SELECT_USES_HEAP */
406 : 0 : return ret;
407 : : }
408 : :
409 : : #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
410 : : /*
411 : : * poll() support
412 : : */
413 : :
414 : : typedef struct {
415 : : PyObject_HEAD
416 : : PyObject *dict;
417 : : int ufd_uptodate;
418 : : int ufd_len;
419 : : struct pollfd *ufds;
420 : : int poll_running;
421 : : } pollObject;
422 : :
423 : : /* Update the malloc'ed array of pollfds to match the dictionary
424 : : contained within a pollObject. Return 1 on success, 0 on an error.
425 : : */
426 : :
427 : : static int
428 : 0 : update_ufd_array(pollObject *self)
429 : : {
430 : : Py_ssize_t i, pos;
431 : : PyObject *key, *value;
432 : 0 : struct pollfd *old_ufds = self->ufds;
433 : :
434 : 0 : self->ufd_len = PyDict_GET_SIZE(self->dict);
435 [ # # ]: 0 : PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
436 [ # # ]: 0 : if (self->ufds == NULL) {
437 : 0 : self->ufds = old_ufds;
438 : 0 : PyErr_NoMemory();
439 : 0 : return 0;
440 : : }
441 : :
442 : 0 : i = pos = 0;
443 [ # # ]: 0 : while (PyDict_Next(self->dict, &pos, &key, &value)) {
444 : : assert(i < self->ufd_len);
445 : : /* Never overflow */
446 : 0 : self->ufds[i].fd = (int)PyLong_AsLong(key);
447 : 0 : self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
448 : 0 : i++;
449 : : }
450 : : assert(i == self->ufd_len);
451 : 0 : self->ufd_uptodate = 1;
452 : 0 : return 1;
453 : : }
454 : :
455 : : /*[clinic input]
456 : : select.poll.register
457 : :
458 : : fd: fildes
459 : : either an integer, or an object with a fileno() method returning an int
460 : : eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
461 : : an optional bitmask describing the type of events to check for
462 : : /
463 : :
464 : : Register a file descriptor with the polling object.
465 : : [clinic start generated code]*/
466 : :
467 : : static PyObject *
468 : 0 : select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
469 : : /*[clinic end generated code: output=0dc7173c800a4a65 input=34e16cfb28d3c900]*/
470 : : {
471 : : PyObject *key, *value;
472 : : int err;
473 : :
474 : : /* Add entry to the internal dictionary: the key is the
475 : : file descriptor, and the value is the event mask. */
476 : 0 : key = PyLong_FromLong(fd);
477 [ # # ]: 0 : if (key == NULL)
478 : 0 : return NULL;
479 : 0 : value = PyLong_FromLong(eventmask);
480 [ # # ]: 0 : if (value == NULL) {
481 : 0 : Py_DECREF(key);
482 : 0 : return NULL;
483 : : }
484 : 0 : err = PyDict_SetItem(self->dict, key, value);
485 : 0 : Py_DECREF(key);
486 : 0 : Py_DECREF(value);
487 [ # # ]: 0 : if (err < 0)
488 : 0 : return NULL;
489 : :
490 : 0 : self->ufd_uptodate = 0;
491 : :
492 : 0 : Py_RETURN_NONE;
493 : : }
494 : :
495 : :
496 : : /*[clinic input]
497 : : select.poll.modify
498 : :
499 : : fd: fildes
500 : : either an integer, or an object with a fileno() method returning
501 : : an int
502 : : eventmask: unsigned_short
503 : : a bitmask describing the type of events to check for
504 : : /
505 : :
506 : : Modify an already registered file descriptor.
507 : : [clinic start generated code]*/
508 : :
509 : : static PyObject *
510 : 0 : select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
511 : : /*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
512 : : {
513 : : PyObject *key, *value;
514 : : int err;
515 : :
516 : : /* Modify registered fd */
517 : 0 : key = PyLong_FromLong(fd);
518 [ # # ]: 0 : if (key == NULL)
519 : 0 : return NULL;
520 : 0 : err = PyDict_Contains(self->dict, key);
521 [ # # ]: 0 : if (err < 0) {
522 : 0 : Py_DECREF(key);
523 : 0 : return NULL;
524 : : }
525 [ # # ]: 0 : if (err == 0) {
526 : 0 : errno = ENOENT;
527 : 0 : PyErr_SetFromErrno(PyExc_OSError);
528 : 0 : Py_DECREF(key);
529 : 0 : return NULL;
530 : : }
531 : 0 : value = PyLong_FromLong(eventmask);
532 [ # # ]: 0 : if (value == NULL) {
533 : 0 : Py_DECREF(key);
534 : 0 : return NULL;
535 : : }
536 : 0 : err = PyDict_SetItem(self->dict, key, value);
537 : 0 : Py_DECREF(key);
538 : 0 : Py_DECREF(value);
539 [ # # ]: 0 : if (err < 0)
540 : 0 : return NULL;
541 : :
542 : 0 : self->ufd_uptodate = 0;
543 : :
544 : 0 : Py_RETURN_NONE;
545 : : }
546 : :
547 : :
548 : : /*[clinic input]
549 : : select.poll.unregister
550 : :
551 : : fd: fildes
552 : : /
553 : :
554 : : Remove a file descriptor being tracked by the polling object.
555 : : [clinic start generated code]*/
556 : :
557 : : static PyObject *
558 : 0 : select_poll_unregister_impl(pollObject *self, int fd)
559 : : /*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/
560 : : {
561 : : PyObject *key;
562 : :
563 : : /* Check whether the fd is already in the array */
564 : 0 : key = PyLong_FromLong(fd);
565 [ # # ]: 0 : if (key == NULL)
566 : 0 : return NULL;
567 : :
568 [ # # ]: 0 : if (PyDict_DelItem(self->dict, key) == -1) {
569 : 0 : Py_DECREF(key);
570 : : /* This will simply raise the KeyError set by PyDict_DelItem
571 : : if the file descriptor isn't registered. */
572 : 0 : return NULL;
573 : : }
574 : :
575 : 0 : Py_DECREF(key);
576 : 0 : self->ufd_uptodate = 0;
577 : :
578 : 0 : Py_RETURN_NONE;
579 : : }
580 : :
581 : : /*[clinic input]
582 : : select.poll.poll
583 : :
584 : : timeout as timeout_obj: object = None
585 : : The maximum time to wait in milliseconds, or else None (or a negative
586 : : value) to wait indefinitely.
587 : : /
588 : :
589 : : Polls the set of registered file descriptors.
590 : :
591 : : Returns a list containing any descriptors that have events or errors to
592 : : report, as a list of (fd, event) 2-tuples.
593 : : [clinic start generated code]*/
594 : :
595 : : static PyObject *
596 : 0 : select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
597 : : /*[clinic end generated code: output=876e837d193ed7e4 input=c2f6953ec45e5622]*/
598 : : {
599 : 0 : PyObject *result_list = NULL;
600 : : int poll_result, i, j;
601 : 0 : PyObject *value = NULL, *num = NULL;
602 : 0 : _PyTime_t timeout = -1, ms = -1, deadline = 0;
603 : 0 : int async_err = 0;
604 : :
605 [ # # ]: 0 : if (timeout_obj != Py_None) {
606 [ # # ]: 0 : if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
607 : : _PyTime_ROUND_TIMEOUT) < 0) {
608 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
609 : 0 : PyErr_SetString(PyExc_TypeError,
610 : : "timeout must be an integer or None");
611 : : }
612 : 0 : return NULL;
613 : : }
614 : :
615 : 0 : ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
616 [ # # # # ]: 0 : if (ms < INT_MIN || ms > INT_MAX) {
617 : 0 : PyErr_SetString(PyExc_OverflowError, "timeout is too large");
618 : 0 : return NULL;
619 : : }
620 : :
621 [ # # ]: 0 : if (timeout >= 0) {
622 : 0 : deadline = _PyDeadline_Init(timeout);
623 : : }
624 : : }
625 : :
626 : : /* On some OSes, typically BSD-based ones, the timeout parameter of the
627 : : poll() syscall, when negative, must be exactly INFTIM, where defined,
628 : : or -1. See issue 31334. */
629 [ # # ]: 0 : if (ms < 0) {
630 : : #ifdef INFTIM
631 : : ms = INFTIM;
632 : : #else
633 : 0 : ms = -1;
634 : : #endif
635 : : }
636 : :
637 : : /* Avoid concurrent poll() invocation, issue 8865 */
638 [ # # ]: 0 : if (self->poll_running) {
639 : 0 : PyErr_SetString(PyExc_RuntimeError,
640 : : "concurrent poll() invocation");
641 : 0 : return NULL;
642 : : }
643 : :
644 : : /* Ensure the ufd array is up to date */
645 [ # # ]: 0 : if (!self->ufd_uptodate)
646 [ # # ]: 0 : if (update_ufd_array(self) == 0)
647 : 0 : return NULL;
648 : :
649 : 0 : self->poll_running = 1;
650 : :
651 : : /* call poll() */
652 : 0 : async_err = 0;
653 : : do {
654 : 0 : Py_BEGIN_ALLOW_THREADS
655 : 0 : errno = 0;
656 : 0 : poll_result = poll(self->ufds, self->ufd_len, (int)ms);
657 : 0 : Py_END_ALLOW_THREADS
658 : :
659 [ # # ]: 0 : if (errno != EINTR)
660 : 0 : break;
661 : :
662 : : /* poll() was interrupted by a signal */
663 [ # # ]: 0 : if (PyErr_CheckSignals()) {
664 : 0 : async_err = 1;
665 : 0 : break;
666 : : }
667 : :
668 [ # # ]: 0 : if (timeout >= 0) {
669 : 0 : timeout = _PyDeadline_Get(deadline);
670 [ # # ]: 0 : if (timeout < 0) {
671 : 0 : poll_result = 0;
672 : 0 : break;
673 : : }
674 : 0 : ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
675 : : /* retry poll() with the recomputed timeout */
676 : : }
677 : : } while (1);
678 : :
679 : 0 : self->poll_running = 0;
680 : :
681 [ # # ]: 0 : if (poll_result < 0) {
682 [ # # ]: 0 : if (!async_err)
683 : 0 : PyErr_SetFromErrno(PyExc_OSError);
684 : 0 : return NULL;
685 : : }
686 : :
687 : : /* build the result list */
688 : :
689 : 0 : result_list = PyList_New(poll_result);
690 [ # # ]: 0 : if (!result_list)
691 : 0 : return NULL;
692 : :
693 [ # # ]: 0 : for (i = 0, j = 0; j < poll_result; j++) {
694 : : /* skip to the next fired descriptor */
695 [ # # ]: 0 : while (!self->ufds[i].revents) {
696 : 0 : i++;
697 : : }
698 : : /* if we hit a NULL return, set value to NULL
699 : : and break out of loop; code at end will
700 : : clean up result_list */
701 : 0 : value = PyTuple_New(2);
702 [ # # ]: 0 : if (value == NULL)
703 : 0 : goto error;
704 : 0 : num = PyLong_FromLong(self->ufds[i].fd);
705 [ # # ]: 0 : if (num == NULL) {
706 : 0 : Py_DECREF(value);
707 : 0 : goto error;
708 : : }
709 : 0 : PyTuple_SET_ITEM(value, 0, num);
710 : :
711 : : /* The &0xffff is a workaround for AIX. 'revents'
712 : : is a 16-bit short, and IBM assigned POLLNVAL
713 : : to be 0x8000, so the conversion to int results
714 : : in a negative number. See SF bug #923315. */
715 : 0 : num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
716 [ # # ]: 0 : if (num == NULL) {
717 : 0 : Py_DECREF(value);
718 : 0 : goto error;
719 : : }
720 : 0 : PyTuple_SET_ITEM(value, 1, num);
721 : 0 : PyList_SET_ITEM(result_list, j, value);
722 : 0 : i++;
723 : : }
724 : 0 : return result_list;
725 : :
726 : 0 : error:
727 : 0 : Py_DECREF(result_list);
728 : 0 : return NULL;
729 : : }
730 : :
731 : : static pollObject *
732 : 0 : newPollObject(PyObject *module)
733 : : {
734 : : pollObject *self;
735 : 0 : self = PyObject_New(pollObject, get_select_state(module)->poll_Type);
736 [ # # ]: 0 : if (self == NULL)
737 : 0 : return NULL;
738 : : /* ufd_uptodate is a Boolean, denoting whether the
739 : : array pointed to by ufds matches the contents of the dictionary. */
740 : 0 : self->ufd_uptodate = 0;
741 : 0 : self->ufds = NULL;
742 : 0 : self->poll_running = 0;
743 : 0 : self->dict = PyDict_New();
744 [ # # ]: 0 : if (self->dict == NULL) {
745 : 0 : Py_DECREF(self);
746 : 0 : return NULL;
747 : : }
748 : 0 : return self;
749 : : }
750 : :
751 : : static void
752 : 0 : poll_dealloc(pollObject *self)
753 : : {
754 : 0 : PyObject* type = (PyObject *)Py_TYPE(self);
755 [ # # ]: 0 : if (self->ufds != NULL)
756 : 0 : PyMem_Free(self->ufds);
757 : 0 : Py_XDECREF(self->dict);
758 : 0 : PyObject_Free(self);
759 : 0 : Py_DECREF(type);
760 : 0 : }
761 : :
762 : :
763 : : #ifdef HAVE_SYS_DEVPOLL_H
764 : : static PyMethodDef devpoll_methods[];
765 : :
766 : : typedef struct {
767 : : PyObject_HEAD
768 : : int fd_devpoll;
769 : : int max_n_fds;
770 : : int n_fds;
771 : : struct pollfd *fds;
772 : : } devpollObject;
773 : :
774 : : static PyObject *
775 : : devpoll_err_closed(void)
776 : : {
777 : : PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
778 : : return NULL;
779 : : }
780 : :
781 : : static int devpoll_flush(devpollObject *self)
782 : : {
783 : : int size, n;
784 : :
785 : : if (!self->n_fds) return 0;
786 : :
787 : : size = sizeof(struct pollfd)*self->n_fds;
788 : : self->n_fds = 0;
789 : :
790 : : n = _Py_write(self->fd_devpoll, self->fds, size);
791 : : if (n == -1)
792 : : return -1;
793 : :
794 : : if (n < size) {
795 : : /*
796 : : ** Data writed to /dev/poll is a binary data structure. It is not
797 : : ** clear what to do if a partial write occurred. For now, raise
798 : : ** an exception and see if we actually found this problem in
799 : : ** the wild.
800 : : ** See http://bugs.python.org/issue6397.
801 : : */
802 : : PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
803 : : "Please, report at http://bugs.python.org/. "
804 : : "Data to report: Size tried: %d, actual size written: %d.",
805 : : size, n);
806 : : return -1;
807 : : }
808 : : return 0;
809 : : }
810 : :
811 : : static PyObject *
812 : : internal_devpoll_register(devpollObject *self, int fd,
813 : : unsigned short events, int remove)
814 : : {
815 : : if (self->fd_devpoll < 0)
816 : : return devpoll_err_closed();
817 : :
818 : : if (remove) {
819 : : self->fds[self->n_fds].fd = fd;
820 : : self->fds[self->n_fds].events = POLLREMOVE;
821 : :
822 : : if (++self->n_fds == self->max_n_fds) {
823 : : if (devpoll_flush(self))
824 : : return NULL;
825 : : }
826 : : }
827 : :
828 : : self->fds[self->n_fds].fd = fd;
829 : : self->fds[self->n_fds].events = (signed short)events;
830 : :
831 : : if (++self->n_fds == self->max_n_fds) {
832 : : if (devpoll_flush(self))
833 : : return NULL;
834 : : }
835 : :
836 : : Py_RETURN_NONE;
837 : : }
838 : :
839 : : /*[clinic input]
840 : : select.devpoll.register
841 : :
842 : : fd: fildes
843 : : either an integer, or an object with a fileno() method returning
844 : : an int
845 : : eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
846 : : an optional bitmask describing the type of events to check for
847 : : /
848 : :
849 : : Register a file descriptor with the polling object.
850 : : [clinic start generated code]*/
851 : :
852 : : static PyObject *
853 : : select_devpoll_register_impl(devpollObject *self, int fd,
854 : : unsigned short eventmask)
855 : : /*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/
856 : : {
857 : : return internal_devpoll_register(self, fd, eventmask, 0);
858 : : }
859 : :
860 : : /*[clinic input]
861 : : select.devpoll.modify
862 : :
863 : : fd: fildes
864 : : either an integer, or an object with a fileno() method returning
865 : : an int
866 : : eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT
867 : : an optional bitmask describing the type of events to check for
868 : : /
869 : :
870 : : Modify a possible already registered file descriptor.
871 : : [clinic start generated code]*/
872 : :
873 : : static PyObject *
874 : : select_devpoll_modify_impl(devpollObject *self, int fd,
875 : : unsigned short eventmask)
876 : : /*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/
877 : : {
878 : : return internal_devpoll_register(self, fd, eventmask, 1);
879 : : }
880 : :
881 : : /*[clinic input]
882 : : select.devpoll.unregister
883 : :
884 : : fd: fildes
885 : : /
886 : :
887 : : Remove a file descriptor being tracked by the polling object.
888 : : [clinic start generated code]*/
889 : :
890 : : static PyObject *
891 : : select_devpoll_unregister_impl(devpollObject *self, int fd)
892 : : /*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/
893 : : {
894 : : if (self->fd_devpoll < 0)
895 : : return devpoll_err_closed();
896 : :
897 : : self->fds[self->n_fds].fd = fd;
898 : : self->fds[self->n_fds].events = POLLREMOVE;
899 : :
900 : : if (++self->n_fds == self->max_n_fds) {
901 : : if (devpoll_flush(self))
902 : : return NULL;
903 : : }
904 : :
905 : : Py_RETURN_NONE;
906 : : }
907 : :
908 : : /*[clinic input]
909 : : select.devpoll.poll
910 : : timeout as timeout_obj: object = None
911 : : The maximum time to wait in milliseconds, or else None (or a negative
912 : : value) to wait indefinitely.
913 : : /
914 : :
915 : : Polls the set of registered file descriptors.
916 : :
917 : : Returns a list containing any descriptors that have events or errors to
918 : : report, as a list of (fd, event) 2-tuples.
919 : : [clinic start generated code]*/
920 : :
921 : : static PyObject *
922 : : select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj)
923 : : /*[clinic end generated code: output=2654e5457cca0b3c input=3c3f0a355ec2bedb]*/
924 : : {
925 : : struct dvpoll dvp;
926 : : PyObject *result_list = NULL;
927 : : int poll_result, i;
928 : : PyObject *value, *num1, *num2;
929 : : _PyTime_t timeout, ms, deadline = 0;
930 : :
931 : : if (self->fd_devpoll < 0)
932 : : return devpoll_err_closed();
933 : :
934 : : /* Check values for timeout */
935 : : if (timeout_obj == Py_None) {
936 : : timeout = -1;
937 : : ms = -1;
938 : : }
939 : : else {
940 : : if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
941 : : _PyTime_ROUND_TIMEOUT) < 0) {
942 : : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
943 : : PyErr_SetString(PyExc_TypeError,
944 : : "timeout must be an integer or None");
945 : : }
946 : : return NULL;
947 : : }
948 : :
949 : : ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
950 : : if (ms < -1 || ms > INT_MAX) {
951 : : PyErr_SetString(PyExc_OverflowError, "timeout is too large");
952 : : return NULL;
953 : : }
954 : : }
955 : :
956 : : if (devpoll_flush(self))
957 : : return NULL;
958 : :
959 : : dvp.dp_fds = self->fds;
960 : : dvp.dp_nfds = self->max_n_fds;
961 : : dvp.dp_timeout = (int)ms;
962 : :
963 : : if (timeout >= 0) {
964 : : deadline = _PyDeadline_Init(timeout);
965 : : }
966 : :
967 : : do {
968 : : /* call devpoll() */
969 : : Py_BEGIN_ALLOW_THREADS
970 : : errno = 0;
971 : : poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
972 : : Py_END_ALLOW_THREADS
973 : :
974 : : if (errno != EINTR)
975 : : break;
976 : :
977 : : /* devpoll() was interrupted by a signal */
978 : : if (PyErr_CheckSignals())
979 : : return NULL;
980 : :
981 : : if (timeout >= 0) {
982 : : timeout = _PyDeadline_Get(deadline);
983 : : if (timeout < 0) {
984 : : poll_result = 0;
985 : : break;
986 : : }
987 : : ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
988 : : dvp.dp_timeout = (int)ms;
989 : : /* retry devpoll() with the recomputed timeout */
990 : : }
991 : : } while (1);
992 : :
993 : : if (poll_result < 0) {
994 : : PyErr_SetFromErrno(PyExc_OSError);
995 : : return NULL;
996 : : }
997 : :
998 : : /* build the result list */
999 : : result_list = PyList_New(poll_result);
1000 : : if (!result_list)
1001 : : return NULL;
1002 : :
1003 : : for (i = 0; i < poll_result; i++) {
1004 : : num1 = PyLong_FromLong(self->fds[i].fd);
1005 : : num2 = PyLong_FromLong(self->fds[i].revents);
1006 : : if ((num1 == NULL) || (num2 == NULL)) {
1007 : : Py_XDECREF(num1);
1008 : : Py_XDECREF(num2);
1009 : : goto error;
1010 : : }
1011 : : value = PyTuple_Pack(2, num1, num2);
1012 : : Py_DECREF(num1);
1013 : : Py_DECREF(num2);
1014 : : if (value == NULL)
1015 : : goto error;
1016 : : PyList_SET_ITEM(result_list, i, value);
1017 : : }
1018 : :
1019 : : return result_list;
1020 : :
1021 : : error:
1022 : : Py_DECREF(result_list);
1023 : : return NULL;
1024 : : }
1025 : :
1026 : : static int
1027 : : devpoll_internal_close(devpollObject *self)
1028 : : {
1029 : : int save_errno = 0;
1030 : : if (self->fd_devpoll >= 0) {
1031 : : int fd = self->fd_devpoll;
1032 : : self->fd_devpoll = -1;
1033 : : Py_BEGIN_ALLOW_THREADS
1034 : : if (close(fd) < 0)
1035 : : save_errno = errno;
1036 : : Py_END_ALLOW_THREADS
1037 : : }
1038 : : return save_errno;
1039 : : }
1040 : :
1041 : : /*[clinic input]
1042 : : select.devpoll.close
1043 : :
1044 : : Close the devpoll file descriptor.
1045 : :
1046 : : Further operations on the devpoll object will raise an exception.
1047 : : [clinic start generated code]*/
1048 : :
1049 : : static PyObject *
1050 : : select_devpoll_close_impl(devpollObject *self)
1051 : : /*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/
1052 : : {
1053 : : errno = devpoll_internal_close(self);
1054 : : if (errno < 0) {
1055 : : PyErr_SetFromErrno(PyExc_OSError);
1056 : : return NULL;
1057 : : }
1058 : : Py_RETURN_NONE;
1059 : : }
1060 : :
1061 : : static PyObject*
1062 : : devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
1063 : : {
1064 : : if (self->fd_devpoll < 0)
1065 : : Py_RETURN_TRUE;
1066 : : else
1067 : : Py_RETURN_FALSE;
1068 : : }
1069 : :
1070 : : /*[clinic input]
1071 : : select.devpoll.fileno
1072 : :
1073 : : Return the file descriptor.
1074 : : [clinic start generated code]*/
1075 : :
1076 : : static PyObject *
1077 : : select_devpoll_fileno_impl(devpollObject *self)
1078 : : /*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/
1079 : : {
1080 : : if (self->fd_devpoll < 0)
1081 : : return devpoll_err_closed();
1082 : : return PyLong_FromLong(self->fd_devpoll);
1083 : : }
1084 : :
1085 : : static PyGetSetDef devpoll_getsetlist[] = {
1086 : : {"closed", (getter)devpoll_get_closed, NULL,
1087 : : "True if the devpoll object is closed"},
1088 : : {0},
1089 : : };
1090 : :
1091 : : static devpollObject *
1092 : : newDevPollObject(PyObject *module)
1093 : : {
1094 : : devpollObject *self;
1095 : : int fd_devpoll, limit_result;
1096 : : struct pollfd *fds;
1097 : : struct rlimit limit;
1098 : :
1099 : : /*
1100 : : ** If we try to process more that getrlimit()
1101 : : ** fds, the kernel will give an error, so
1102 : : ** we set the limit here. It is a dynamic
1103 : : ** value, because we can change rlimit() anytime.
1104 : : */
1105 : : limit_result = getrlimit(RLIMIT_NOFILE, &limit);
1106 : : if (limit_result == -1) {
1107 : : PyErr_SetFromErrno(PyExc_OSError);
1108 : : return NULL;
1109 : : }
1110 : :
1111 : : fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1112 : : if (fd_devpoll == -1)
1113 : : return NULL;
1114 : :
1115 : : fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1116 : : if (fds == NULL) {
1117 : : close(fd_devpoll);
1118 : : PyErr_NoMemory();
1119 : : return NULL;
1120 : : }
1121 : :
1122 : : self = PyObject_New(devpollObject, get_select_state(module)->devpoll_Type);
1123 : : if (self == NULL) {
1124 : : close(fd_devpoll);
1125 : : PyMem_Free(fds);
1126 : : return NULL;
1127 : : }
1128 : : self->fd_devpoll = fd_devpoll;
1129 : : self->max_n_fds = limit.rlim_cur;
1130 : : self->n_fds = 0;
1131 : : self->fds = fds;
1132 : :
1133 : : return self;
1134 : : }
1135 : :
1136 : : static void
1137 : : devpoll_dealloc(devpollObject *self)
1138 : : {
1139 : : PyObject *type = (PyObject *)Py_TYPE(self);
1140 : : (void)devpoll_internal_close(self);
1141 : : PyMem_Free(self->fds);
1142 : : PyObject_Free(self);
1143 : : Py_DECREF(type);
1144 : : }
1145 : :
1146 : : static PyType_Slot devpoll_Type_slots[] = {
1147 : : {Py_tp_dealloc, devpoll_dealloc},
1148 : : {Py_tp_getset, devpoll_getsetlist},
1149 : : {Py_tp_methods, devpoll_methods},
1150 : : {0, 0},
1151 : : };
1152 : :
1153 : : static PyType_Spec devpoll_Type_spec = {
1154 : : "select.devpoll",
1155 : : sizeof(devpollObject),
1156 : : 0,
1157 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
1158 : : devpoll_Type_slots
1159 : : };
1160 : :
1161 : : #endif /* HAVE_SYS_DEVPOLL_H */
1162 : :
1163 : :
1164 : : /*[clinic input]
1165 : : select.poll
1166 : :
1167 : : Returns a polling object.
1168 : :
1169 : : This object supports registering and unregistering file descriptors, and then
1170 : : polling them for I/O events.
1171 : : [clinic start generated code]*/
1172 : :
1173 : : static PyObject *
1174 : 0 : select_poll_impl(PyObject *module)
1175 : : /*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/
1176 : : {
1177 : 0 : return (PyObject *)newPollObject(module);
1178 : : }
1179 : :
1180 : : #ifdef HAVE_SYS_DEVPOLL_H
1181 : :
1182 : : /*[clinic input]
1183 : : select.devpoll
1184 : :
1185 : : Returns a polling object.
1186 : :
1187 : : This object supports registering and unregistering file descriptors, and then
1188 : : polling them for I/O events.
1189 : : [clinic start generated code]*/
1190 : :
1191 : : static PyObject *
1192 : : select_devpoll_impl(PyObject *module)
1193 : : /*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/
1194 : : {
1195 : : return (PyObject *)newDevPollObject(module);
1196 : : }
1197 : : #endif
1198 : :
1199 : :
1200 : : #ifdef __APPLE__
1201 : : /*
1202 : : * On some systems poll() sets errno on invalid file descriptors. We test
1203 : : * for this at runtime because this bug may be fixed or introduced between
1204 : : * OS releases.
1205 : : */
1206 : : static int select_have_broken_poll(void)
1207 : : {
1208 : : int poll_test;
1209 : : int filedes[2];
1210 : :
1211 : : struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
1212 : :
1213 : : /* Create a file descriptor to make invalid */
1214 : : if (pipe(filedes) < 0) {
1215 : : return 1;
1216 : : }
1217 : : poll_struct.fd = filedes[0];
1218 : : close(filedes[0]);
1219 : : close(filedes[1]);
1220 : : poll_test = poll(&poll_struct, 1, 0);
1221 : : if (poll_test < 0) {
1222 : : return 1;
1223 : : } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1224 : : return 1;
1225 : : }
1226 : : return 0;
1227 : : }
1228 : : #endif /* __APPLE__ */
1229 : :
1230 : : #endif /* HAVE_POLL */
1231 : :
1232 : : #ifdef HAVE_EPOLL
1233 : : /* **************************************************************************
1234 : : * epoll interface for Linux 2.6
1235 : : *
1236 : : * Written by Christian Heimes
1237 : : * Inspired by Twisted's _epoll.pyx and select.poll()
1238 : : */
1239 : :
1240 : : #ifdef HAVE_SYS_EPOLL_H
1241 : : #include <sys/epoll.h>
1242 : : #endif
1243 : :
1244 : : typedef struct {
1245 : : PyObject_HEAD
1246 : : SOCKET epfd; /* epoll control file descriptor */
1247 : : } pyEpoll_Object;
1248 : :
1249 : : static PyObject *
1250 : 0 : pyepoll_err_closed(void)
1251 : : {
1252 : 0 : PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
1253 : 0 : return NULL;
1254 : : }
1255 : :
1256 : : static int
1257 : 2 : pyepoll_internal_close(pyEpoll_Object *self)
1258 : : {
1259 : 2 : int save_errno = 0;
1260 [ + + ]: 2 : if (self->epfd >= 0) {
1261 : 1 : int epfd = self->epfd;
1262 : 1 : self->epfd = -1;
1263 : 1 : Py_BEGIN_ALLOW_THREADS
1264 [ - + ]: 1 : if (close(epfd) < 0)
1265 : 0 : save_errno = errno;
1266 : 1 : Py_END_ALLOW_THREADS
1267 : : }
1268 : 2 : return save_errno;
1269 : : }
1270 : :
1271 : : static PyObject *
1272 : 1 : newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
1273 : : {
1274 : : pyEpoll_Object *self;
1275 : : assert(type != NULL);
1276 : 1 : allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc);
1277 : : assert(epoll_alloc != NULL);
1278 : 1 : self = (pyEpoll_Object *) epoll_alloc(type, 0);
1279 [ - + ]: 1 : if (self == NULL)
1280 : 0 : return NULL;
1281 : :
1282 [ + - ]: 1 : if (fd == -1) {
1283 : 1 : Py_BEGIN_ALLOW_THREADS
1284 : : #ifdef HAVE_EPOLL_CREATE1
1285 : 1 : self->epfd = epoll_create1(EPOLL_CLOEXEC);
1286 : : #else
1287 : : self->epfd = epoll_create(sizehint);
1288 : : #endif
1289 : 1 : Py_END_ALLOW_THREADS
1290 : : }
1291 : : else {
1292 : 0 : self->epfd = fd;
1293 : : }
1294 [ - + ]: 1 : if (self->epfd < 0) {
1295 : 0 : Py_DECREF(self);
1296 : 0 : PyErr_SetFromErrno(PyExc_OSError);
1297 : 0 : return NULL;
1298 : : }
1299 : :
1300 : : #ifndef HAVE_EPOLL_CREATE1
1301 : : if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
1302 : : Py_DECREF(self);
1303 : : return NULL;
1304 : : }
1305 : : #endif
1306 : :
1307 : 1 : return (PyObject *)self;
1308 : : }
1309 : :
1310 : :
1311 : : /*[clinic input]
1312 : : @classmethod
1313 : : select.epoll.__new__
1314 : :
1315 : : sizehint: int = -1
1316 : : The expected number of events to be registered. It must be positive,
1317 : : or -1 to use the default. It is only used on older systems where
1318 : : epoll_create1() is not available; otherwise it has no effect (though its
1319 : : value is still checked).
1320 : : flags: int = 0
1321 : : Deprecated and completely ignored. However, when supplied, its value
1322 : : must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.
1323 : :
1324 : : Returns an epolling object.
1325 : : [clinic start generated code]*/
1326 : :
1327 : : static PyObject *
1328 : 1 : select_epoll_impl(PyTypeObject *type, int sizehint, int flags)
1329 : : /*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/
1330 : : {
1331 [ + - ]: 1 : if (sizehint == -1) {
1332 : 1 : sizehint = FD_SETSIZE - 1;
1333 : : }
1334 [ # # ]: 0 : else if (sizehint <= 0) {
1335 : 0 : PyErr_SetString(PyExc_ValueError, "negative sizehint");
1336 : 0 : return NULL;
1337 : : }
1338 : :
1339 : : #ifdef HAVE_EPOLL_CREATE1
1340 [ - + - - ]: 1 : if (flags && flags != EPOLL_CLOEXEC) {
1341 : 0 : PyErr_SetString(PyExc_OSError, "invalid flags");
1342 : 0 : return NULL;
1343 : : }
1344 : : #endif
1345 : :
1346 : 1 : return newPyEpoll_Object(type, sizehint, -1);
1347 : : }
1348 : :
1349 : :
1350 : : static void
1351 : 1 : pyepoll_dealloc(pyEpoll_Object *self)
1352 : : {
1353 : 1 : PyTypeObject* type = Py_TYPE(self);
1354 : 1 : (void)pyepoll_internal_close(self);
1355 : 1 : freefunc epoll_free = PyType_GetSlot(type, Py_tp_free);
1356 : 1 : epoll_free((PyObject *)self);
1357 : 1 : Py_DECREF((PyObject *)type);
1358 : 1 : }
1359 : :
1360 : : /*[clinic input]
1361 : : select.epoll.close
1362 : :
1363 : : Close the epoll control file descriptor.
1364 : :
1365 : : Further operations on the epoll object will raise an exception.
1366 : : [clinic start generated code]*/
1367 : :
1368 : : static PyObject *
1369 : 1 : select_epoll_close_impl(pyEpoll_Object *self)
1370 : : /*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/
1371 : : {
1372 : 1 : errno = pyepoll_internal_close(self);
1373 [ - + ]: 1 : if (errno < 0) {
1374 : 0 : PyErr_SetFromErrno(PyExc_OSError);
1375 : 0 : return NULL;
1376 : : }
1377 : 1 : Py_RETURN_NONE;
1378 : : }
1379 : :
1380 : :
1381 : : static PyObject*
1382 : 0 : pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
1383 : : {
1384 [ # # ]: 0 : if (self->epfd < 0)
1385 : 0 : Py_RETURN_TRUE;
1386 : : else
1387 : 0 : Py_RETURN_FALSE;
1388 : : }
1389 : :
1390 : : /*[clinic input]
1391 : : select.epoll.fileno
1392 : :
1393 : : Return the epoll control file descriptor.
1394 : : [clinic start generated code]*/
1395 : :
1396 : : static PyObject *
1397 : 0 : select_epoll_fileno_impl(pyEpoll_Object *self)
1398 : : /*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/
1399 : : {
1400 [ # # ]: 0 : if (self->epfd < 0)
1401 : 0 : return pyepoll_err_closed();
1402 : 0 : return PyLong_FromLong(self->epfd);
1403 : : }
1404 : :
1405 : :
1406 : : /*[clinic input]
1407 : : @classmethod
1408 : : select.epoll.fromfd
1409 : :
1410 : : fd: int
1411 : : /
1412 : :
1413 : : Create an epoll object from a given control fd.
1414 : : [clinic start generated code]*/
1415 : :
1416 : : static PyObject *
1417 : 0 : select_epoll_fromfd_impl(PyTypeObject *type, int fd)
1418 : : /*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/
1419 : : {
1420 : 0 : SOCKET s_fd = (SOCKET)fd;
1421 : 0 : return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd);
1422 : : }
1423 : :
1424 : :
1425 : : static PyObject *
1426 : 0 : pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events)
1427 : : {
1428 : : struct epoll_event ev;
1429 : : int result;
1430 : :
1431 [ # # ]: 0 : if (epfd < 0)
1432 : 0 : return pyepoll_err_closed();
1433 : :
1434 [ # # # ]: 0 : switch (op) {
1435 : 0 : case EPOLL_CTL_ADD:
1436 : : case EPOLL_CTL_MOD:
1437 : 0 : ev.events = events;
1438 : 0 : ev.data.fd = fd;
1439 : 0 : Py_BEGIN_ALLOW_THREADS
1440 : 0 : result = epoll_ctl(epfd, op, fd, &ev);
1441 : 0 : Py_END_ALLOW_THREADS
1442 : 0 : break;
1443 : 0 : case EPOLL_CTL_DEL:
1444 : : /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1445 : : * operation required a non-NULL pointer in event, even
1446 : : * though this argument is ignored. */
1447 : 0 : Py_BEGIN_ALLOW_THREADS
1448 : 0 : result = epoll_ctl(epfd, op, fd, &ev);
1449 : 0 : Py_END_ALLOW_THREADS
1450 : 0 : break;
1451 : 0 : default:
1452 : 0 : result = -1;
1453 : 0 : errno = EINVAL;
1454 : : }
1455 : :
1456 [ # # ]: 0 : if (result < 0) {
1457 : 0 : PyErr_SetFromErrno(PyExc_OSError);
1458 : 0 : return NULL;
1459 : : }
1460 : 0 : Py_RETURN_NONE;
1461 : : }
1462 : :
1463 : : /*[clinic input]
1464 : : select.epoll.register
1465 : :
1466 : : fd: fildes
1467 : : the target file descriptor of the operation
1468 : : eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT
1469 : : a bit set composed of the various EPOLL constants
1470 : :
1471 : : Registers a new fd or raises an OSError if the fd is already registered.
1472 : :
1473 : : The epoll interface supports all file descriptors that support poll.
1474 : : [clinic start generated code]*/
1475 : :
1476 : : static PyObject *
1477 : 0 : select_epoll_register_impl(pyEpoll_Object *self, int fd,
1478 : : unsigned int eventmask)
1479 : : /*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/
1480 : : {
1481 : 0 : return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask);
1482 : : }
1483 : :
1484 : : /*[clinic input]
1485 : : select.epoll.modify
1486 : :
1487 : : fd: fildes
1488 : : the target file descriptor of the operation
1489 : : eventmask: unsigned_int(bitwise=True)
1490 : : a bit set composed of the various EPOLL constants
1491 : :
1492 : : Modify event mask for a registered file descriptor.
1493 : : [clinic start generated code]*/
1494 : :
1495 : : static PyObject *
1496 : 0 : select_epoll_modify_impl(pyEpoll_Object *self, int fd,
1497 : : unsigned int eventmask)
1498 : : /*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/
1499 : : {
1500 : 0 : return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask);
1501 : : }
1502 : :
1503 : : /*[clinic input]
1504 : : select.epoll.unregister
1505 : :
1506 : : fd: fildes
1507 : : the target file descriptor of the operation
1508 : :
1509 : : Remove a registered file descriptor from the epoll object.
1510 : : [clinic start generated code]*/
1511 : :
1512 : : static PyObject *
1513 : 0 : select_epoll_unregister_impl(pyEpoll_Object *self, int fd)
1514 : : /*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/
1515 : : {
1516 : 0 : return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0);
1517 : : }
1518 : :
1519 : : /*[clinic input]
1520 : : select.epoll.poll
1521 : :
1522 : : timeout as timeout_obj: object = None
1523 : : the maximum time to wait in seconds (as float);
1524 : : a timeout of None or -1 makes poll wait indefinitely
1525 : : maxevents: int = -1
1526 : : the maximum number of events returned; -1 means no limit
1527 : :
1528 : : Wait for events on the epoll file descriptor.
1529 : :
1530 : : Returns a list containing any descriptors that have events to report,
1531 : : as a list of (fd, events) 2-tuples.
1532 : : [clinic start generated code]*/
1533 : :
1534 : : static PyObject *
1535 : 0 : select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj,
1536 : : int maxevents)
1537 : : /*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/
1538 : : {
1539 : : int nfds, i;
1540 : 0 : PyObject *elist = NULL, *etuple = NULL;
1541 : 0 : struct epoll_event *evs = NULL;
1542 : 0 : _PyTime_t timeout = -1, ms = -1, deadline = 0;
1543 : :
1544 [ # # ]: 0 : if (self->epfd < 0)
1545 : 0 : return pyepoll_err_closed();
1546 : :
1547 [ # # ]: 0 : if (timeout_obj != Py_None) {
1548 : : /* epoll_wait() has a resolution of 1 millisecond, round towards
1549 : : infinity to wait at least timeout seconds. */
1550 [ # # ]: 0 : if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
1551 : : _PyTime_ROUND_TIMEOUT) < 0) {
1552 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1553 : 0 : PyErr_SetString(PyExc_TypeError,
1554 : : "timeout must be an integer or None");
1555 : : }
1556 : 0 : return NULL;
1557 : : }
1558 : :
1559 : 0 : ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1560 [ # # # # ]: 0 : if (ms < INT_MIN || ms > INT_MAX) {
1561 : 0 : PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1562 : 0 : return NULL;
1563 : : }
1564 : : /* epoll_wait(2) treats all arbitrary negative numbers the same
1565 : : for the timeout argument, but -1 is the documented way to block
1566 : : indefinitely in the epoll_wait(2) documentation, so we set ms
1567 : : to -1 if the value of ms is a negative number.
1568 : :
1569 : : Note that we didn't use INFTIM here since it's non-standard and
1570 : : isn't available under Linux. */
1571 [ # # ]: 0 : if (ms < 0) {
1572 : 0 : ms = -1;
1573 : : }
1574 : :
1575 [ # # ]: 0 : if (timeout >= 0) {
1576 : 0 : deadline = _PyDeadline_Init(timeout);
1577 : : }
1578 : : }
1579 : :
1580 [ # # ]: 0 : if (maxevents == -1) {
1581 : 0 : maxevents = FD_SETSIZE-1;
1582 : : }
1583 [ # # ]: 0 : else if (maxevents < 1) {
1584 : 0 : PyErr_Format(PyExc_ValueError,
1585 : : "maxevents must be greater than 0, got %d",
1586 : : maxevents);
1587 : 0 : return NULL;
1588 : : }
1589 : :
1590 [ # # ]: 0 : evs = PyMem_New(struct epoll_event, maxevents);
1591 [ # # ]: 0 : if (evs == NULL) {
1592 : 0 : PyErr_NoMemory();
1593 : 0 : return NULL;
1594 : : }
1595 : :
1596 : : do {
1597 : 0 : Py_BEGIN_ALLOW_THREADS
1598 : 0 : errno = 0;
1599 : 0 : nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1600 : 0 : Py_END_ALLOW_THREADS
1601 : :
1602 [ # # ]: 0 : if (errno != EINTR)
1603 : 0 : break;
1604 : :
1605 : : /* poll() was interrupted by a signal */
1606 [ # # ]: 0 : if (PyErr_CheckSignals())
1607 : 0 : goto error;
1608 : :
1609 [ # # ]: 0 : if (timeout >= 0) {
1610 : 0 : timeout = _PyDeadline_Get(deadline);
1611 [ # # ]: 0 : if (timeout < 0) {
1612 : 0 : nfds = 0;
1613 : 0 : break;
1614 : : }
1615 : 0 : ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1616 : : /* retry epoll_wait() with the recomputed timeout */
1617 : : }
1618 : : } while(1);
1619 : :
1620 [ # # ]: 0 : if (nfds < 0) {
1621 : 0 : PyErr_SetFromErrno(PyExc_OSError);
1622 : 0 : goto error;
1623 : : }
1624 : :
1625 : 0 : elist = PyList_New(nfds);
1626 [ # # ]: 0 : if (elist == NULL) {
1627 : 0 : goto error;
1628 : : }
1629 : :
1630 [ # # ]: 0 : for (i = 0; i < nfds; i++) {
1631 : 0 : etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
1632 [ # # ]: 0 : if (etuple == NULL) {
1633 [ # # ]: 0 : Py_CLEAR(elist);
1634 : 0 : goto error;
1635 : : }
1636 : 0 : PyList_SET_ITEM(elist, i, etuple);
1637 : : }
1638 : :
1639 : 0 : error:
1640 : 0 : PyMem_Free(evs);
1641 : 0 : return elist;
1642 : : }
1643 : :
1644 : :
1645 : : /*[clinic input]
1646 : : select.epoll.__enter__
1647 : :
1648 : : [clinic start generated code]*/
1649 : :
1650 : : static PyObject *
1651 : 0 : select_epoll___enter___impl(pyEpoll_Object *self)
1652 : : /*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/
1653 : : {
1654 [ # # ]: 0 : if (self->epfd < 0)
1655 : 0 : return pyepoll_err_closed();
1656 : :
1657 : 0 : return Py_NewRef(self);
1658 : : }
1659 : :
1660 : : /*[clinic input]
1661 : : select.epoll.__exit__
1662 : :
1663 : : exc_type: object = None
1664 : : exc_value: object = None
1665 : : exc_tb: object = None
1666 : : /
1667 : :
1668 : : [clinic start generated code]*/
1669 : :
1670 : : static PyObject *
1671 : 0 : select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type,
1672 : : PyObject *exc_value, PyObject *exc_tb)
1673 : : /*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/
1674 : : {
1675 : 0 : _selectstate *state = _selectstate_by_type(Py_TYPE(self));
1676 : 0 : return PyObject_CallMethodObjArgs((PyObject *)self, state->close, NULL);
1677 : : }
1678 : :
1679 : : static PyGetSetDef pyepoll_getsetlist[] = {
1680 : : {"closed", (getter)pyepoll_get_closed, NULL,
1681 : : "True if the epoll handler is closed"},
1682 : : {0},
1683 : : };
1684 : :
1685 : : PyDoc_STRVAR(pyepoll_doc,
1686 : : "select.epoll(sizehint=-1, flags=0)\n\
1687 : : \n\
1688 : : Returns an epolling object\n\
1689 : : \n\
1690 : : sizehint must be a positive integer or -1 for the default size. The\n\
1691 : : sizehint is used to optimize internal data structures. It doesn't limit\n\
1692 : : the maximum number of monitored events.");
1693 : :
1694 : : #endif /* HAVE_EPOLL */
1695 : :
1696 : : #ifdef HAVE_KQUEUE
1697 : : /* **************************************************************************
1698 : : * kqueue interface for BSD
1699 : : *
1700 : : * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1701 : : * All rights reserved.
1702 : : *
1703 : : * Redistribution and use in source and binary forms, with or without
1704 : : * modification, are permitted provided that the following conditions
1705 : : * are met:
1706 : : * 1. Redistributions of source code must retain the above copyright
1707 : : * notice, this list of conditions and the following disclaimer.
1708 : : * 2. Redistributions in binary form must reproduce the above copyright
1709 : : * notice, this list of conditions and the following disclaimer in the
1710 : : * documentation and/or other materials provided with the distribution.
1711 : : *
1712 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1713 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1714 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1715 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1716 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1717 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1718 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1719 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1720 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1721 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1722 : : * SUCH DAMAGE.
1723 : : */
1724 : :
1725 : : #ifdef HAVE_SYS_EVENT_H
1726 : : #include <sys/event.h>
1727 : : #endif
1728 : :
1729 : : PyDoc_STRVAR(kqueue_event_doc,
1730 : : "kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
1731 : : \n\
1732 : : This object is the equivalent of the struct kevent for the C API.\n\
1733 : : \n\
1734 : : See the kqueue manpage for more detailed information about the meaning\n\
1735 : : of the arguments.\n\
1736 : : \n\
1737 : : One minor note: while you might hope that udata could store a\n\
1738 : : reference to a python object, it cannot, because it is impossible to\n\
1739 : : keep a proper reference count of the object once it's passed into the\n\
1740 : : kernel. Therefore, I have restricted it to only storing an integer. I\n\
1741 : : recommend ignoring it and simply using the 'ident' field to key off\n\
1742 : : of. You could also set up a dictionary on the python side to store a\n\
1743 : : udata->object mapping.");
1744 : :
1745 : : typedef struct {
1746 : : PyObject_HEAD
1747 : : struct kevent e;
1748 : : } kqueue_event_Object;
1749 : :
1750 : : #define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type))
1751 : :
1752 : : typedef struct {
1753 : : PyObject_HEAD
1754 : : SOCKET kqfd; /* kqueue control fd */
1755 : : } kqueue_queue_Object;
1756 : :
1757 : : #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1758 : : # error uintptr_t does not match void *!
1759 : : #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1760 : : # define T_UINTPTRT T_ULONGLONG
1761 : : # define T_INTPTRT T_LONGLONG
1762 : : # define UINTPTRT_FMT_UNIT "K"
1763 : : # define INTPTRT_FMT_UNIT "L"
1764 : : #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1765 : : # define T_UINTPTRT T_ULONG
1766 : : # define T_INTPTRT T_LONG
1767 : : # define UINTPTRT_FMT_UNIT "k"
1768 : : # define INTPTRT_FMT_UNIT "l"
1769 : : #elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1770 : : # define T_UINTPTRT T_UINT
1771 : : # define T_INTPTRT T_INT
1772 : : # define UINTPTRT_FMT_UNIT "I"
1773 : : # define INTPTRT_FMT_UNIT "i"
1774 : : #else
1775 : : # error uintptr_t does not match int, long, or long long!
1776 : : #endif
1777 : :
1778 : : #if SIZEOF_LONG_LONG == 8
1779 : : # define T_INT64 T_LONGLONG
1780 : : # define INT64_FMT_UNIT "L"
1781 : : #elif SIZEOF_LONG == 8
1782 : : # define T_INT64 T_LONG
1783 : : # define INT64_FMT_UNIT "l"
1784 : : #elif SIZEOF_INT == 8
1785 : : # define T_INT64 T_INT
1786 : : # define INT64_FMT_UNIT "i"
1787 : : #else
1788 : : # define INT64_FMT_UNIT "_"
1789 : : #endif
1790 : :
1791 : : #if SIZEOF_LONG_LONG == 4
1792 : : # define T_UINT32 T_ULONGLONG
1793 : : # define UINT32_FMT_UNIT "K"
1794 : : #elif SIZEOF_LONG == 4
1795 : : # define T_UINT32 T_ULONG
1796 : : # define UINT32_FMT_UNIT "k"
1797 : : #elif SIZEOF_INT == 4
1798 : : # define T_UINT32 T_UINT
1799 : : # define UINT32_FMT_UNIT "I"
1800 : : #else
1801 : : # define UINT32_FMT_UNIT "_"
1802 : : #endif
1803 : :
1804 : : /*
1805 : : * kevent is not standard and its members vary across BSDs.
1806 : : */
1807 : : #ifdef __NetBSD__
1808 : : # define FILTER_TYPE T_UINT32
1809 : : # define FILTER_FMT_UNIT UINT32_FMT_UNIT
1810 : : # define FLAGS_TYPE T_UINT32
1811 : : # define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1812 : : # define FFLAGS_TYPE T_UINT32
1813 : : # define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
1814 : : #else
1815 : : # define FILTER_TYPE T_SHORT
1816 : : # define FILTER_FMT_UNIT "h"
1817 : : # define FLAGS_TYPE T_USHORT
1818 : : # define FLAGS_FMT_UNIT "H"
1819 : : # define FFLAGS_TYPE T_UINT
1820 : : # define FFLAGS_FMT_UNIT "I"
1821 : : #endif
1822 : :
1823 : : #if defined(__NetBSD__) || defined(__OpenBSD__)
1824 : : # define DATA_TYPE T_INT64
1825 : : # define DATA_FMT_UNIT INT64_FMT_UNIT
1826 : : #else
1827 : : # define DATA_TYPE T_INTPTRT
1828 : : # define DATA_FMT_UNIT INTPTRT_FMT_UNIT
1829 : : #endif
1830 : :
1831 : : /* Unfortunately, we can't store python objects in udata, because
1832 : : * kevents in the kernel can be removed without warning, which would
1833 : : * forever lose the refcount on the object stored with it.
1834 : : */
1835 : :
1836 : : #define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1837 : : static struct PyMemberDef kqueue_event_members[] = {
1838 : : {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1839 : : {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1840 : : {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
1841 : : {"fflags", T_UINT, KQ_OFF(e.fflags)},
1842 : : {"data", DATA_TYPE, KQ_OFF(e.data)},
1843 : : {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1844 : : {NULL} /* Sentinel */
1845 : : };
1846 : : #undef KQ_OFF
1847 : :
1848 : : static PyObject *
1849 : :
1850 : : kqueue_event_repr(kqueue_event_Object *s)
1851 : : {
1852 : : char buf[1024];
1853 : : PyOS_snprintf(
1854 : : buf, sizeof(buf),
1855 : : "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1856 : : "data=0x%llx udata=%p>",
1857 : : (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1858 : : (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
1859 : : return PyUnicode_FromString(buf);
1860 : : }
1861 : :
1862 : : static int
1863 : : kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1864 : : {
1865 : : PyObject *pfd;
1866 : : static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1867 : : "data", "udata", NULL};
1868 : : static const char fmt[] = "O|"
1869 : : FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1870 : : UINTPTRT_FMT_UNIT ":kevent";
1871 : :
1872 : : EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
1873 : :
1874 : : if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1875 : : &pfd, &(self->e.filter), &(self->e.flags),
1876 : : &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1877 : : return -1;
1878 : : }
1879 : :
1880 : : if (PyLong_Check(pfd)) {
1881 : : self->e.ident = PyLong_AsSize_t(pfd);
1882 : : }
1883 : : else {
1884 : : self->e.ident = PyObject_AsFileDescriptor(pfd);
1885 : : }
1886 : : if (PyErr_Occurred()) {
1887 : : return -1;
1888 : : }
1889 : : return 0;
1890 : : }
1891 : :
1892 : : static PyObject *
1893 : : kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
1894 : : int op)
1895 : : {
1896 : : int result;
1897 : : _selectstate *state = _selectstate_by_type(Py_TYPE(s));
1898 : :
1899 : : if (!kqueue_event_Check(o, state)) {
1900 : : Py_RETURN_NOTIMPLEMENTED;
1901 : : }
1902 : :
1903 : : #define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1904 : : result = CMP(s->e.ident, o->e.ident)
1905 : : : CMP(s->e.filter, o->e.filter)
1906 : : : CMP(s->e.flags, o->e.flags)
1907 : : : CMP(s->e.fflags, o->e.fflags)
1908 : : : CMP(s->e.data, o->e.data)
1909 : : : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1910 : : : 0;
1911 : : #undef CMP
1912 : :
1913 : : Py_RETURN_RICHCOMPARE(result, 0, op);
1914 : : }
1915 : :
1916 : : static PyType_Slot kqueue_event_Type_slots[] = {
1917 : : {Py_tp_doc, (void*)kqueue_event_doc},
1918 : : {Py_tp_init, kqueue_event_init},
1919 : : {Py_tp_members, kqueue_event_members},
1920 : : {Py_tp_new, PyType_GenericNew},
1921 : : {Py_tp_repr, kqueue_event_repr},
1922 : : {Py_tp_richcompare, kqueue_event_richcompare},
1923 : : {0, 0},
1924 : : };
1925 : :
1926 : : static PyType_Spec kqueue_event_Type_spec = {
1927 : : "select.kevent",
1928 : : sizeof(kqueue_event_Object),
1929 : : 0,
1930 : : Py_TPFLAGS_DEFAULT,
1931 : : kqueue_event_Type_slots
1932 : : };
1933 : :
1934 : : static PyObject *
1935 : : kqueue_queue_err_closed(void)
1936 : : {
1937 : : PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
1938 : : return NULL;
1939 : : }
1940 : :
1941 : : static int
1942 : : kqueue_queue_internal_close(kqueue_queue_Object *self)
1943 : : {
1944 : : int save_errno = 0;
1945 : : if (self->kqfd >= 0) {
1946 : : int kqfd = self->kqfd;
1947 : : self->kqfd = -1;
1948 : : Py_BEGIN_ALLOW_THREADS
1949 : : if (close(kqfd) < 0)
1950 : : save_errno = errno;
1951 : : Py_END_ALLOW_THREADS
1952 : : }
1953 : : return save_errno;
1954 : : }
1955 : :
1956 : : static PyObject *
1957 : : newKqueue_Object(PyTypeObject *type, SOCKET fd)
1958 : : {
1959 : : kqueue_queue_Object *self;
1960 : : assert(type != NULL);
1961 : : allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc);
1962 : : assert(queue_alloc != NULL);
1963 : : self = (kqueue_queue_Object *) queue_alloc(type, 0);
1964 : : if (self == NULL) {
1965 : : return NULL;
1966 : : }
1967 : :
1968 : : if (fd == -1) {
1969 : : Py_BEGIN_ALLOW_THREADS
1970 : : self->kqfd = kqueue();
1971 : : Py_END_ALLOW_THREADS
1972 : : }
1973 : : else {
1974 : : self->kqfd = fd;
1975 : : }
1976 : : if (self->kqfd < 0) {
1977 : : Py_DECREF(self);
1978 : : PyErr_SetFromErrno(PyExc_OSError);
1979 : : return NULL;
1980 : : }
1981 : :
1982 : : if (fd == -1) {
1983 : : if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1984 : : Py_DECREF(self);
1985 : : return NULL;
1986 : : }
1987 : : }
1988 : : return (PyObject *)self;
1989 : : }
1990 : :
1991 : : /*[clinic input]
1992 : : @classmethod
1993 : : select.kqueue.__new__
1994 : :
1995 : : Kqueue syscall wrapper.
1996 : :
1997 : : For example, to start watching a socket for input:
1998 : : >>> kq = kqueue()
1999 : : >>> sock = socket()
2000 : : >>> sock.connect((host, port))
2001 : : >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)
2002 : :
2003 : : To wait one second for it to become writeable:
2004 : : >>> kq.control(None, 1, 1000)
2005 : :
2006 : : To stop listening:
2007 : : >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)
2008 : : [clinic start generated code]*/
2009 : :
2010 : : static PyObject *
2011 : : select_kqueue_impl(PyTypeObject *type)
2012 : : /*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/
2013 : : {
2014 : : return newKqueue_Object(type, -1);
2015 : : }
2016 : :
2017 : : static void
2018 : : kqueue_queue_dealloc(kqueue_queue_Object *self)
2019 : : {
2020 : : PyTypeObject* type = Py_TYPE(self);
2021 : : kqueue_queue_internal_close(self);
2022 : : freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free);
2023 : : kqueue_free((PyObject *)self);
2024 : : Py_DECREF((PyObject *)type);
2025 : : }
2026 : :
2027 : : /*[clinic input]
2028 : : select.kqueue.close
2029 : :
2030 : : Close the kqueue control file descriptor.
2031 : :
2032 : : Further operations on the kqueue object will raise an exception.
2033 : : [clinic start generated code]*/
2034 : :
2035 : : static PyObject *
2036 : : select_kqueue_close_impl(kqueue_queue_Object *self)
2037 : : /*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/
2038 : : {
2039 : : errno = kqueue_queue_internal_close(self);
2040 : : if (errno < 0) {
2041 : : PyErr_SetFromErrno(PyExc_OSError);
2042 : : return NULL;
2043 : : }
2044 : : Py_RETURN_NONE;
2045 : : }
2046 : :
2047 : : static PyObject*
2048 : : kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
2049 : : {
2050 : : if (self->kqfd < 0)
2051 : : Py_RETURN_TRUE;
2052 : : else
2053 : : Py_RETURN_FALSE;
2054 : : }
2055 : :
2056 : : /*[clinic input]
2057 : : select.kqueue.fileno
2058 : :
2059 : : Return the kqueue control file descriptor.
2060 : : [clinic start generated code]*/
2061 : :
2062 : : static PyObject *
2063 : : select_kqueue_fileno_impl(kqueue_queue_Object *self)
2064 : : /*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/
2065 : : {
2066 : : if (self->kqfd < 0)
2067 : : return kqueue_queue_err_closed();
2068 : : return PyLong_FromLong(self->kqfd);
2069 : : }
2070 : :
2071 : : /*[clinic input]
2072 : : @classmethod
2073 : : select.kqueue.fromfd
2074 : :
2075 : : fd: int
2076 : : /
2077 : :
2078 : : Create a kqueue object from a given control fd.
2079 : : [clinic start generated code]*/
2080 : :
2081 : : static PyObject *
2082 : : select_kqueue_fromfd_impl(PyTypeObject *type, int fd)
2083 : : /*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/
2084 : : {
2085 : : SOCKET s_fd = (SOCKET)fd;
2086 : :
2087 : : return newKqueue_Object(type, s_fd);
2088 : : }
2089 : :
2090 : : /*[clinic input]
2091 : : select.kqueue.control
2092 : :
2093 : : changelist: object
2094 : : Must be an iterable of kevent objects describing the changes to be made
2095 : : to the kernel's watch list or None.
2096 : : maxevents: int
2097 : : The maximum number of events that the kernel will return.
2098 : : timeout as otimeout: object = None
2099 : : The maximum time to wait in seconds, or else None to wait forever.
2100 : : This accepts floats for smaller timeouts, too.
2101 : : /
2102 : :
2103 : : Calls the kernel kevent function.
2104 : : [clinic start generated code]*/
2105 : :
2106 : : static PyObject *
2107 : : select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist,
2108 : : int maxevents, PyObject *otimeout)
2109 : : /*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/
2110 : : {
2111 : : int gotevents = 0;
2112 : : int nchanges = 0;
2113 : : int i = 0;
2114 : : PyObject *seq = NULL, *ei = NULL;
2115 : : PyObject *result = NULL;
2116 : : struct kevent *evl = NULL;
2117 : : struct kevent *chl = NULL;
2118 : : struct timespec timeoutspec;
2119 : : struct timespec *ptimeoutspec;
2120 : : _PyTime_t timeout, deadline = 0;
2121 : : _selectstate *state = _selectstate_by_type(Py_TYPE(self));
2122 : :
2123 : : if (self->kqfd < 0)
2124 : : return kqueue_queue_err_closed();
2125 : :
2126 : : if (maxevents < 0) {
2127 : : PyErr_Format(PyExc_ValueError,
2128 : : "Length of eventlist must be 0 or positive, got %d",
2129 : : maxevents);
2130 : : return NULL;
2131 : : }
2132 : :
2133 : : if (otimeout == Py_None) {
2134 : : ptimeoutspec = NULL;
2135 : : }
2136 : : else {
2137 : : if (_PyTime_FromSecondsObject(&timeout,
2138 : : otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
2139 : : PyErr_Format(PyExc_TypeError,
2140 : : "timeout argument must be a number "
2141 : : "or None, got %.200s",
2142 : : _PyType_Name(Py_TYPE(otimeout)));
2143 : : return NULL;
2144 : : }
2145 : :
2146 : : if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2147 : : return NULL;
2148 : :
2149 : : if (timeoutspec.tv_sec < 0) {
2150 : : PyErr_SetString(PyExc_ValueError,
2151 : : "timeout must be positive or None");
2152 : : return NULL;
2153 : : }
2154 : : ptimeoutspec = &timeoutspec;
2155 : : }
2156 : :
2157 : : if (changelist != Py_None) {
2158 : : seq = PySequence_Fast(changelist, "changelist is not iterable");
2159 : : if (seq == NULL) {
2160 : : return NULL;
2161 : : }
2162 : : if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2163 : : PyErr_SetString(PyExc_OverflowError,
2164 : : "changelist is too long");
2165 : : goto error;
2166 : : }
2167 : : nchanges = (int)PySequence_Fast_GET_SIZE(seq);
2168 : :
2169 : : chl = PyMem_New(struct kevent, nchanges);
2170 : : if (chl == NULL) {
2171 : : PyErr_NoMemory();
2172 : : goto error;
2173 : : }
2174 : : _selectstate *state = _selectstate_by_type(Py_TYPE(self));
2175 : : for (i = 0; i < nchanges; ++i) {
2176 : : ei = PySequence_Fast_GET_ITEM(seq, i);
2177 : : if (!kqueue_event_Check(ei, state)) {
2178 : : PyErr_SetString(PyExc_TypeError,
2179 : : "changelist must be an iterable of "
2180 : : "select.kevent objects");
2181 : : goto error;
2182 : : }
2183 : : chl[i] = ((kqueue_event_Object *)ei)->e;
2184 : : }
2185 : : Py_CLEAR(seq);
2186 : : }
2187 : :
2188 : : /* event list */
2189 : : if (maxevents) {
2190 : : evl = PyMem_New(struct kevent, maxevents);
2191 : : if (evl == NULL) {
2192 : : PyErr_NoMemory();
2193 : : goto error;
2194 : : }
2195 : : }
2196 : :
2197 : : if (ptimeoutspec) {
2198 : : deadline = _PyDeadline_Init(timeout);
2199 : : }
2200 : :
2201 : : do {
2202 : : Py_BEGIN_ALLOW_THREADS
2203 : : errno = 0;
2204 : : gotevents = kevent(self->kqfd, chl, nchanges,
2205 : : evl, maxevents, ptimeoutspec);
2206 : : Py_END_ALLOW_THREADS
2207 : :
2208 : : if (errno != EINTR)
2209 : : break;
2210 : :
2211 : : /* kevent() was interrupted by a signal */
2212 : : if (PyErr_CheckSignals())
2213 : : goto error;
2214 : :
2215 : : if (ptimeoutspec) {
2216 : : timeout = _PyDeadline_Get(deadline);
2217 : : if (timeout < 0) {
2218 : : gotevents = 0;
2219 : : break;
2220 : : }
2221 : : if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2222 : : goto error;
2223 : : /* retry kevent() with the recomputed timeout */
2224 : : }
2225 : : } while (1);
2226 : :
2227 : : if (gotevents == -1) {
2228 : : PyErr_SetFromErrno(PyExc_OSError);
2229 : : goto error;
2230 : : }
2231 : :
2232 : : result = PyList_New(gotevents);
2233 : : if (result == NULL) {
2234 : : goto error;
2235 : : }
2236 : :
2237 : : for (i = 0; i < gotevents; i++) {
2238 : : kqueue_event_Object *ch;
2239 : :
2240 : : ch = PyObject_New(kqueue_event_Object, state->kqueue_event_Type);
2241 : : if (ch == NULL) {
2242 : : goto error;
2243 : : }
2244 : : ch->e = evl[i];
2245 : : PyList_SET_ITEM(result, i, (PyObject *)ch);
2246 : : }
2247 : : PyMem_Free(chl);
2248 : : PyMem_Free(evl);
2249 : : return result;
2250 : :
2251 : : error:
2252 : : PyMem_Free(chl);
2253 : : PyMem_Free(evl);
2254 : : Py_XDECREF(result);
2255 : : Py_XDECREF(seq);
2256 : : return NULL;
2257 : : }
2258 : :
2259 : : static PyGetSetDef kqueue_queue_getsetlist[] = {
2260 : : {"closed", (getter)kqueue_queue_get_closed, NULL,
2261 : : "True if the kqueue handler is closed"},
2262 : : {0},
2263 : : };
2264 : :
2265 : : #endif /* HAVE_KQUEUE */
2266 : :
2267 : :
2268 : : /* ************************************************************************ */
2269 : :
2270 : : #include "clinic/selectmodule.c.h"
2271 : :
2272 : : #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2273 : :
2274 : : static PyMethodDef poll_methods[] = {
2275 : : SELECT_POLL_REGISTER_METHODDEF
2276 : : SELECT_POLL_MODIFY_METHODDEF
2277 : : SELECT_POLL_UNREGISTER_METHODDEF
2278 : : SELECT_POLL_POLL_METHODDEF
2279 : : {NULL, NULL} /* sentinel */
2280 : : };
2281 : :
2282 : :
2283 : : static PyType_Slot poll_Type_slots[] = {
2284 : : {Py_tp_dealloc, poll_dealloc},
2285 : : {Py_tp_methods, poll_methods},
2286 : : {0, 0},
2287 : : };
2288 : :
2289 : : static PyType_Spec poll_Type_spec = {
2290 : : .name = "select.poll",
2291 : : .basicsize = sizeof(pollObject),
2292 : : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
2293 : : .slots = poll_Type_slots,
2294 : : };
2295 : :
2296 : : #ifdef HAVE_SYS_DEVPOLL_H
2297 : :
2298 : : static PyMethodDef devpoll_methods[] = {
2299 : : SELECT_DEVPOLL_REGISTER_METHODDEF
2300 : : SELECT_DEVPOLL_MODIFY_METHODDEF
2301 : : SELECT_DEVPOLL_UNREGISTER_METHODDEF
2302 : : SELECT_DEVPOLL_POLL_METHODDEF
2303 : : SELECT_DEVPOLL_CLOSE_METHODDEF
2304 : : SELECT_DEVPOLL_FILENO_METHODDEF
2305 : : {NULL, NULL} /* sentinel */
2306 : : };
2307 : :
2308 : : #endif /* HAVE_SYS_DEVPOLL_H */
2309 : :
2310 : : #endif /* HAVE_POLL */
2311 : :
2312 : : #ifdef HAVE_EPOLL
2313 : :
2314 : : static PyMethodDef pyepoll_methods[] = {
2315 : : SELECT_EPOLL_FROMFD_METHODDEF
2316 : : SELECT_EPOLL_CLOSE_METHODDEF
2317 : : SELECT_EPOLL_FILENO_METHODDEF
2318 : : SELECT_EPOLL_MODIFY_METHODDEF
2319 : : SELECT_EPOLL_REGISTER_METHODDEF
2320 : : SELECT_EPOLL_UNREGISTER_METHODDEF
2321 : : SELECT_EPOLL_POLL_METHODDEF
2322 : : SELECT_EPOLL___ENTER___METHODDEF
2323 : : SELECT_EPOLL___EXIT___METHODDEF
2324 : : {NULL, NULL},
2325 : : };
2326 : :
2327 : : static PyType_Slot pyEpoll_Type_slots[] = {
2328 : : {Py_tp_dealloc, pyepoll_dealloc},
2329 : : {Py_tp_doc, (void*)pyepoll_doc},
2330 : : {Py_tp_getattro, PyObject_GenericGetAttr},
2331 : : {Py_tp_getset, pyepoll_getsetlist},
2332 : : {Py_tp_methods, pyepoll_methods},
2333 : : {Py_tp_new, select_epoll},
2334 : : {0, 0},
2335 : : };
2336 : :
2337 : : static PyType_Spec pyEpoll_Type_spec = {
2338 : : "select.epoll",
2339 : : sizeof(pyEpoll_Object),
2340 : : 0,
2341 : : Py_TPFLAGS_DEFAULT,
2342 : : pyEpoll_Type_slots
2343 : : };
2344 : :
2345 : : #endif /* HAVE_EPOLL */
2346 : :
2347 : : #ifdef HAVE_KQUEUE
2348 : :
2349 : : static PyMethodDef kqueue_queue_methods[] = {
2350 : : SELECT_KQUEUE_FROMFD_METHODDEF
2351 : : SELECT_KQUEUE_CLOSE_METHODDEF
2352 : : SELECT_KQUEUE_FILENO_METHODDEF
2353 : : SELECT_KQUEUE_CONTROL_METHODDEF
2354 : : {NULL, NULL},
2355 : : };
2356 : :
2357 : : static PyType_Slot kqueue_queue_Type_slots[] = {
2358 : : {Py_tp_dealloc, kqueue_queue_dealloc},
2359 : : {Py_tp_doc, (void*)select_kqueue__doc__},
2360 : : {Py_tp_getset, kqueue_queue_getsetlist},
2361 : : {Py_tp_methods, kqueue_queue_methods},
2362 : : {Py_tp_new, select_kqueue},
2363 : : {0, 0},
2364 : : };
2365 : :
2366 : : static PyType_Spec kqueue_queue_Type_spec = {
2367 : : "select.kqueue",
2368 : : sizeof(kqueue_queue_Object),
2369 : : 0,
2370 : : Py_TPFLAGS_DEFAULT,
2371 : : kqueue_queue_Type_slots
2372 : : };
2373 : :
2374 : : #endif /* HAVE_KQUEUE */
2375 : :
2376 : :
2377 : :
2378 : :
2379 : :
2380 : : /* ************************************************************************ */
2381 : :
2382 : :
2383 : : static PyMethodDef select_methods[] = {
2384 : : SELECT_SELECT_METHODDEF
2385 : : SELECT_POLL_METHODDEF
2386 : : SELECT_DEVPOLL_METHODDEF
2387 : : {0, 0}, /* sentinel */
2388 : : };
2389 : :
2390 : : PyDoc_STRVAR(module_doc,
2391 : : "This module supports asynchronous I/O on multiple file descriptors.\n\
2392 : : \n\
2393 : : *** IMPORTANT NOTICE ***\n\
2394 : : On Windows, only sockets are supported; on Unix, all file descriptors.");
2395 : :
2396 : :
2397 : :
2398 : : static int
2399 : 16 : _select_traverse(PyObject *module, visitproc visit, void *arg)
2400 : : {
2401 : 16 : _selectstate *state = get_select_state(module);
2402 : :
2403 [ + - - + ]: 16 : Py_VISIT(state->close);
2404 [ + - - + ]: 16 : Py_VISIT(state->poll_Type);
2405 [ - + - - ]: 16 : Py_VISIT(state->devpoll_Type);
2406 [ + - - + ]: 16 : Py_VISIT(state->pyEpoll_Type);
2407 [ - + - - ]: 16 : Py_VISIT(state->kqueue_event_Type);
2408 [ - + - - ]: 16 : Py_VISIT(state->kqueue_queue_Type);
2409 : 16 : return 0;
2410 : : }
2411 : :
2412 : : static int
2413 : 4 : _select_clear(PyObject *module)
2414 : : {
2415 : 4 : _selectstate *state = get_select_state(module);
2416 : :
2417 [ + + ]: 4 : Py_CLEAR(state->close);
2418 [ + + ]: 4 : Py_CLEAR(state->poll_Type);
2419 [ - + ]: 4 : Py_CLEAR(state->devpoll_Type);
2420 [ + + ]: 4 : Py_CLEAR(state->pyEpoll_Type);
2421 [ - + ]: 4 : Py_CLEAR(state->kqueue_event_Type);
2422 [ - + ]: 4 : Py_CLEAR(state->kqueue_queue_Type);
2423 : 4 : return 0;
2424 : : }
2425 : :
2426 : : static void
2427 : 2 : _select_free(void *module)
2428 : : {
2429 : 2 : _select_clear((PyObject *)module);
2430 : 2 : }
2431 : :
2432 : : int
2433 : 2 : _select_exec(PyObject *m)
2434 : : {
2435 : 2 : _selectstate *state = get_select_state(m);
2436 : :
2437 : 2 : state->close = PyUnicode_InternFromString("close");
2438 [ - + ]: 2 : if (state->close == NULL) {
2439 : 0 : return -1;
2440 : : }
2441 [ - + ]: 2 : if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) {
2442 : 0 : return -1;
2443 : : }
2444 : :
2445 : : #ifdef PIPE_BUF
2446 : : #ifdef HAVE_BROKEN_PIPE_BUF
2447 : : #undef PIPE_BUF
2448 : : #define PIPE_BUF 512
2449 : : #endif
2450 : 2 : PyModule_AddIntMacro(m, PIPE_BUF);
2451 : : #endif
2452 : :
2453 : : #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
2454 : : #ifdef __APPLE__
2455 : : if (select_have_broken_poll()) {
2456 : : if (PyObject_DelAttrString(m, "poll") == -1) {
2457 : : PyErr_Clear();
2458 : : }
2459 : : } else {
2460 : : #else
2461 : : {
2462 : : #endif
2463 : 2 : state->poll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2464 : : m, &poll_Type_spec, NULL);
2465 [ - + ]: 2 : if (state->poll_Type == NULL) {
2466 : 0 : return -1;
2467 : : }
2468 : :
2469 : 2 : PyModule_AddIntMacro(m, POLLIN);
2470 : 2 : PyModule_AddIntMacro(m, POLLPRI);
2471 : 2 : PyModule_AddIntMacro(m, POLLOUT);
2472 : 2 : PyModule_AddIntMacro(m, POLLERR);
2473 : 2 : PyModule_AddIntMacro(m, POLLHUP);
2474 : 2 : PyModule_AddIntMacro(m, POLLNVAL);
2475 : :
2476 : : #ifdef POLLRDNORM
2477 : 2 : PyModule_AddIntMacro(m, POLLRDNORM);
2478 : : #endif
2479 : : #ifdef POLLRDBAND
2480 : 2 : PyModule_AddIntMacro(m, POLLRDBAND);
2481 : : #endif
2482 : : #ifdef POLLWRNORM
2483 : 2 : PyModule_AddIntMacro(m, POLLWRNORM);
2484 : : #endif
2485 : : #ifdef POLLWRBAND
2486 : 2 : PyModule_AddIntMacro(m, POLLWRBAND);
2487 : : #endif
2488 : : #ifdef POLLMSG
2489 : 2 : PyModule_AddIntMacro(m, POLLMSG);
2490 : : #endif
2491 : : #ifdef POLLRDHUP
2492 : : /* Kernel 2.6.17+ */
2493 : 2 : PyModule_AddIntMacro(m, POLLRDHUP);
2494 : : #endif
2495 : : }
2496 : : #endif /* HAVE_POLL */
2497 : :
2498 : : #ifdef HAVE_SYS_DEVPOLL_H
2499 : : state->devpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2500 : : m, &devpoll_Type_spec, NULL);
2501 : : if (state->devpoll_Type == NULL) {
2502 : : return -1;
2503 : : }
2504 : : #endif
2505 : :
2506 : : #ifdef HAVE_EPOLL
2507 : 2 : state->pyEpoll_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2508 : : m, &pyEpoll_Type_spec, NULL);
2509 [ - + ]: 2 : if (state->pyEpoll_Type == NULL) {
2510 : 0 : return -1;
2511 : : }
2512 [ - + ]: 2 : if (PyModule_AddType(m, state->pyEpoll_Type) < 0) {
2513 : 0 : return -1;
2514 : : }
2515 : :
2516 : 2 : PyModule_AddIntMacro(m, EPOLLIN);
2517 : 2 : PyModule_AddIntMacro(m, EPOLLOUT);
2518 : 2 : PyModule_AddIntMacro(m, EPOLLPRI);
2519 : 2 : PyModule_AddIntMacro(m, EPOLLERR);
2520 : 2 : PyModule_AddIntMacro(m, EPOLLHUP);
2521 : : #ifdef EPOLLRDHUP
2522 : : /* Kernel 2.6.17 */
2523 : 2 : PyModule_AddIntMacro(m, EPOLLRDHUP);
2524 : : #endif
2525 : 2 : PyModule_AddIntMacro(m, EPOLLET);
2526 : : #ifdef EPOLLONESHOT
2527 : : /* Kernel 2.6.2+ */
2528 : 2 : PyModule_AddIntMacro(m, EPOLLONESHOT);
2529 : : #endif
2530 : : #ifdef EPOLLEXCLUSIVE
2531 : 2 : PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2532 : : #endif
2533 : :
2534 : : #ifdef EPOLLRDNORM
2535 : 2 : PyModule_AddIntMacro(m, EPOLLRDNORM);
2536 : : #endif
2537 : : #ifdef EPOLLRDBAND
2538 : 2 : PyModule_AddIntMacro(m, EPOLLRDBAND);
2539 : : #endif
2540 : : #ifdef EPOLLWRNORM
2541 : 2 : PyModule_AddIntMacro(m, EPOLLWRNORM);
2542 : : #endif
2543 : : #ifdef EPOLLWRBAND
2544 : 2 : PyModule_AddIntMacro(m, EPOLLWRBAND);
2545 : : #endif
2546 : : #ifdef EPOLLMSG
2547 : 2 : PyModule_AddIntMacro(m, EPOLLMSG);
2548 : : #endif
2549 : :
2550 : : #ifdef EPOLL_CLOEXEC
2551 : 2 : PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
2552 : : #endif
2553 : : #endif /* HAVE_EPOLL */
2554 : :
2555 : : #ifdef HAVE_KQUEUE
2556 : : state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2557 : : m, &kqueue_event_Type_spec, NULL);
2558 : : if (state->kqueue_event_Type == NULL) {
2559 : : return -1;
2560 : : }
2561 : : if (PyModule_AddType(m, state->kqueue_event_Type) < 0) {
2562 : : return -1;
2563 : : }
2564 : :
2565 : : state->kqueue_queue_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
2566 : : m, &kqueue_queue_Type_spec, NULL);
2567 : : if (state->kqueue_queue_Type == NULL) {
2568 : : return -1;
2569 : : }
2570 : : if (PyModule_AddType(m, state->kqueue_queue_Type) < 0) {
2571 : : return -1;
2572 : : }
2573 : :
2574 : : /* event filters */
2575 : : PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2576 : : PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2577 : : #ifdef EVFILT_AIO
2578 : : PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2579 : : #endif
2580 : : #ifdef EVFILT_VNODE
2581 : : PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2582 : : #endif
2583 : : #ifdef EVFILT_PROC
2584 : : PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
2585 : : #endif
2586 : : #ifdef EVFILT_NETDEV
2587 : : PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
2588 : : #endif
2589 : : #ifdef EVFILT_SIGNAL
2590 : : PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2591 : : #endif
2592 : : PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
2593 : :
2594 : : /* event flags */
2595 : : PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2596 : : PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2597 : : PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2598 : : PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2599 : : PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2600 : : PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
2601 : :
2602 : : #ifdef EV_SYSFLAGS
2603 : : PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2604 : : #endif
2605 : : #ifdef EV_FLAG1
2606 : : PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
2607 : : #endif
2608 : :
2609 : : PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2610 : : PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
2611 : :
2612 : : /* READ WRITE filter flag */
2613 : : #ifdef NOTE_LOWAT
2614 : : PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
2615 : : #endif
2616 : :
2617 : : /* VNODE filter flags */
2618 : : #ifdef EVFILT_VNODE
2619 : : PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2620 : : PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2621 : : PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2622 : : PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2623 : : PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2624 : : PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2625 : : PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
2626 : : #endif
2627 : :
2628 : : /* PROC filter flags */
2629 : : #ifdef EVFILT_PROC
2630 : : PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2631 : : PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2632 : : PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2633 : : PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2634 : : PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
2635 : :
2636 : : PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2637 : : PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2638 : : PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2639 : : #endif
2640 : :
2641 : : /* NETDEV filter flags */
2642 : : #ifdef EVFILT_NETDEV
2643 : : PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2644 : : PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2645 : : PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
2646 : : #endif
2647 : :
2648 : : #endif /* HAVE_KQUEUE */
2649 : 2 : return 0;
2650 : : }
2651 : :
2652 : : static PyModuleDef_Slot _select_slots[] = {
2653 : : {Py_mod_exec, _select_exec},
2654 : : {0, NULL}
2655 : : };
2656 : :
2657 : : static struct PyModuleDef selectmodule = {
2658 : : PyModuleDef_HEAD_INIT,
2659 : : .m_name = "select",
2660 : : .m_doc = module_doc,
2661 : : .m_size = sizeof(_selectstate),
2662 : : .m_methods = select_methods,
2663 : : .m_slots = _select_slots,
2664 : : .m_traverse = _select_traverse,
2665 : : .m_clear = _select_clear,
2666 : : .m_free = _select_free,
2667 : : };
2668 : :
2669 : : PyMODINIT_FUNC
2670 : 2 : PyInit_select(void)
2671 : : {
2672 : 2 : return PyModuleDef_Init(&selectmodule);
2673 : : }
|