blob: 93d896a37c2232fd9cf8789032f786bcd311f00c [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
Barry Warsawc1cb3601996-12-12 22:16:21 +000061/* list of Python objects and their file descriptor */
62typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 PyObject *obj; /* owned reference */
64 SOCKET fd;
65 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000066} pylist;
67
Barry Warsawc1cb3601996-12-12 22:16:21 +000068static void
Tim Peters4b046c22001-08-16 21:59:46 +000069reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000070{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020071 unsigned int i;
72 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +020073 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 }
75 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000076}
77
78
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000079/* returns -1 and sets the Python exception if an error occurred, otherwise
80 returns a number >= 0
81*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000082static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000083seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020086 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010087 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 PyObject* fast_seq = NULL;
89 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
92 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000094 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (!fast_seq)
96 return -1;
97
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010098 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 SOCKET v;
100
101 /* any intervening fileno() calls could decr this refcnt */
102 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200103 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 Py_INCREF(o);
106 v = PyObject_AsFileDescriptor( o );
107 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000108
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000109#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000111#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200112 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 PyErr_SetString(PyExc_ValueError,
114 "filedescriptor out of range in select()");
115 goto finally;
116 }
117 if (v > max)
118 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200123 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 PyErr_SetString(PyExc_ValueError,
125 "too many file descriptors in select()");
126 goto finally;
127 }
128 fd2obj[index].obj = o;
129 fd2obj[index].fd = v;
130 fd2obj[index].sentinel = 0;
131 fd2obj[++index].sentinel = -1;
132 }
133 Py_DECREF(fast_seq);
134 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135
136 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 Py_XDECREF(o);
138 Py_DECREF(fast_seq);
139 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000140}
141
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000142/* returns NULL and sets the Python exception if an error occurred */
143static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 int i, j, count=0;
147 PyObject *list, *o;
148 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
151 if (FD_ISSET(fd2obj[j].fd, set))
152 count++;
153 }
154 list = PyList_New(count);
155 if (!list)
156 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 i = 0;
159 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
160 fd = fd2obj[j].fd;
161 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 o = fd2obj[j].obj;
163 fd2obj[j].obj = NULL;
164 /* transfer ownership */
165 if (PyList_SetItem(list, i, o) < 0)
166 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 i++;
169 }
170 }
171 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 Py_DECREF(list);
174 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000175}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000176
Barry Warsawb44740f2001-08-16 16:52:59 +0000177#undef SELECT_USES_HEAP
178#if FD_SETSIZE > 1024
179#define SELECT_USES_HEAP
180#endif /* FD_SETSIZE > 1024 */
181
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000182static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000183select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000184{
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 /* XXX: All this should probably be implemented as follows:
189 * - find the highest descriptor we're interested in
190 * - add one
191 * - that's the size
192 * See: Stevens, APitUE, $12.5.1
193 */
194 pylist rfd2obj[FD_SETSIZE + 1];
195 pylist wfd2obj[FD_SETSIZE + 1];
196 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000197#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 PyObject *ifdlist, *ofdlist, *efdlist;
199 PyObject *ret = NULL;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200200 PyObject *timeout_obj = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 int imax, omax, emax, max;
204 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200205 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* convert arguments */
208 if (!PyArg_UnpackTuple(args, "select", 3, 4,
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200209 &ifdlist, &ofdlist, &efdlist, &timeout_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000211
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200212 if (timeout_obj == Py_None)
213 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200215 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100216 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200217 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
218 PyErr_SetString(PyExc_TypeError,
219 "timeout must be a float or None");
220 }
Victor Stinnerb2a37732012-03-14 00:20:51 +0100221 return NULL;
222 }
Victor Stinnerc3378382015-03-28 05:07:51 +0100223
Pablo Galindo2c15b292017-10-17 15:14:41 +0100224 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
Victor Stinnerc3378382015-03-28 05:07:51 +0100225 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100226 if (tv.tv_sec < 0) {
227 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 return NULL;
229 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 tvp = &tv;
231 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000232
Barry Warsawb44740f2001-08-16 16:52:59 +0000233#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 /* Allocate memory for the lists */
235 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
236 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
237 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
238 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
239 if (rfd2obj) PyMem_DEL(rfd2obj);
240 if (wfd2obj) PyMem_DEL(wfd2obj);
241 if (efd2obj) PyMem_DEL(efd2obj);
242 return PyErr_NoMemory();
243 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000244#endif /* SELECT_USES_HEAP */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 /* Convert sequences to fd_sets, and get maximum fd number
247 * propagates the Python exception set in seq2set()
248 */
249 rfd2obj[0].sentinel = -1;
250 wfd2obj[0].sentinel = -1;
251 efd2obj[0].sentinel = -1;
252 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
253 goto finally;
254 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
255 goto finally;
256 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
257 goto finally;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 max = imax;
260 if (omax > max) max = omax;
261 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000262
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200263 if (tvp)
264 deadline = _PyTime_GetMonotonicClock() + timeout;
265
266 do {
267 Py_BEGIN_ALLOW_THREADS
268 errno = 0;
269 n = select(max, &ifdset, &ofdset, &efdset, tvp);
270 Py_END_ALLOW_THREADS
271
272 if (errno != EINTR)
273 break;
274
275 /* select() was interrupted by a signal */
276 if (PyErr_CheckSignals())
277 goto finally;
278
279 if (tvp) {
280 timeout = deadline - _PyTime_GetMonotonicClock();
281 if (timeout < 0) {
Miss Islington (bot)34510782018-12-05 13:31:07 -0800282 /* bpo-35310: lists were unmodified -- clear them explicitly */
283 FD_ZERO(&ifdset);
284 FD_ZERO(&ofdset);
285 FD_ZERO(&efdset);
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200286 n = 0;
287 break;
288 }
289 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200290 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200291 }
292 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000293
Thomas Heller106f4c72002-09-24 16:51:00 +0000294#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200296 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000298#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200300 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000302#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 else {
304 /* any of these three calls can raise an exception. it's more
305 convenient to test for this after all three calls... but
306 is that acceptable?
307 */
308 ifdlist = set2list(&ifdset, rfd2obj);
309 ofdlist = set2list(&ofdset, wfd2obj);
310 efdlist = set2list(&efdset, efd2obj);
311 if (PyErr_Occurred())
312 ret = NULL;
313 else
314 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000315
Victor Stinnerbbf8ce52013-07-09 00:49:03 +0200316 Py_XDECREF(ifdlist);
317 Py_XDECREF(ofdlist);
318 Py_XDECREF(efdlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 }
320
Barry Warsawc1cb3601996-12-12 22:16:21 +0000321 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 reap_obj(rfd2obj);
323 reap_obj(wfd2obj);
324 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000325#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 PyMem_DEL(rfd2obj);
327 PyMem_DEL(wfd2obj);
328 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000329#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000331}
332
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000333#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335 * poll() support
336 */
337
338typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 PyObject_HEAD
340 PyObject *dict;
341 int ufd_uptodate;
342 int ufd_len;
343 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300344 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000345} pollObject;
346
Jeremy Hylton938ace62002-07-17 16:30:39 +0000347static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000350 contained within a pollObject. Return 1 on success, 0 on an error.
351*/
352
353static int
354update_ufd_array(pollObject *self)
355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 Py_ssize_t i, pos;
357 PyObject *key, *value;
358 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200360 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
362 if (self->ufds == NULL) {
363 self->ufds = old_ufds;
364 PyErr_NoMemory();
365 return 0;
366 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 i = pos = 0;
369 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200370 assert(i < self->ufd_len);
371 /* Never overflow */
372 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200373 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 i++;
375 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200376 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 self->ufd_uptodate = 1;
378 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000379}
380
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200381static int
382ushort_converter(PyObject *obj, void *ptr)
383{
384 unsigned long uval;
385
386 uval = PyLong_AsUnsignedLong(obj);
387 if (uval == (unsigned long)-1 && PyErr_Occurred())
388 return 0;
389 if (uval > USHRT_MAX) {
390 PyErr_SetString(PyExc_OverflowError,
391 "Python int too large for C unsigned short");
392 return 0;
393 }
394
395 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
396 return 1;
397}
398
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000399PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400"register(fd [, eventmask] ) -> None\n\n\
401Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000402fd -- either an integer, or an object with a fileno() method returning an\n\
403 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000404events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000405
406static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200410 int fd;
411 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000413
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200414 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 fd = PyObject_AsFileDescriptor(o);
418 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 /* Add entry to the internal dictionary: the key is the
421 file descriptor, and the value is the event mask. */
422 key = PyLong_FromLong(fd);
423 if (key == NULL)
424 return NULL;
425 value = PyLong_FromLong(events);
426 if (value == NULL) {
427 Py_DECREF(key);
428 return NULL;
429 }
430 err = PyDict_SetItem(self->dict, key, value);
431 Py_DECREF(key);
432 Py_DECREF(value);
433 if (err < 0)
434 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 self->ufd_uptodate = 0;
437
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200438 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000439}
440
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000441PyDoc_STRVAR(poll_modify_doc,
442"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000443Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000444fd -- either an integer, or an object with a fileno() method returning an\n\
445 int.\n\
446events -- an optional bitmask describing the type of events to check for");
447
448static PyObject *
449poll_modify(pollObject *self, PyObject *args)
450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200452 int fd;
453 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000455
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200456 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 fd = PyObject_AsFileDescriptor(o);
460 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 /* Modify registered fd */
463 key = PyLong_FromLong(fd);
464 if (key == NULL)
465 return NULL;
466 if (PyDict_GetItem(self->dict, key) == NULL) {
467 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200468 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200469 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 return NULL;
471 }
472 value = PyLong_FromLong(events);
473 if (value == NULL) {
474 Py_DECREF(key);
475 return NULL;
476 }
477 err = PyDict_SetItem(self->dict, key, value);
478 Py_DECREF(key);
479 Py_DECREF(value);
480 if (err < 0)
481 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 self->ufd_uptodate = 0;
484
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200485 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000486}
487
488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000489PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000490"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000491Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000492
493static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 PyObject *key;
497 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 fd = PyObject_AsFileDescriptor( o );
500 if (fd == -1)
501 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 /* Check whether the fd is already in the array */
504 key = PyLong_FromLong(fd);
505 if (key == NULL)
506 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 if (PyDict_DelItem(self->dict, key) == -1) {
509 Py_DECREF(key);
510 /* This will simply raise the KeyError set by PyDict_DelItem
511 if the file descriptor isn't registered. */
512 return NULL;
513 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 Py_DECREF(key);
516 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000517
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200518 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000519}
520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000521PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000522"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
523Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000525
526static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000528{
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200529 PyObject *result_list = NULL, *timeout_obj = NULL;
530 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200532 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200533 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000534
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200535 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 return NULL;
537 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000538
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200539 if (timeout_obj != NULL && timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200540 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100541 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200542 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
543 PyErr_SetString(PyExc_TypeError,
544 "timeout must be an integer or None");
545 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200547 }
548
Pablo Galindo2c15b292017-10-17 15:14:41 +0100549 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200550 if (ms < INT_MIN || ms > INT_MAX) {
551 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200553 }
554
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200555 if (timeout >= 0) {
556 deadline = _PyTime_GetMonotonicClock() + timeout;
557 }
558 }
559
560 /* On some OSes, typically BSD-based ones, the timeout parameter of the
561 poll() syscall, when negative, must be exactly INFTIM, where defined,
562 or -1. See issue 31334. */
563 if (ms < 0) {
564#ifdef INFTIM
565 ms = INFTIM;
566#else
567 ms = -1;
568#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000570
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300571 /* Avoid concurrent poll() invocation, issue 8865 */
572 if (self->poll_running) {
573 PyErr_SetString(PyExc_RuntimeError,
574 "concurrent poll() invocation");
575 return NULL;
576 }
577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 /* Ensure the ufd array is up to date */
579 if (!self->ufd_uptodate)
580 if (update_ufd_array(self) == 0)
581 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000582
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300583 self->poll_running = 1;
584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200586 async_err = 0;
587 do {
588 Py_BEGIN_ALLOW_THREADS
589 errno = 0;
590 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
591 Py_END_ALLOW_THREADS
592
593 if (errno != EINTR)
594 break;
595
596 /* poll() was interrupted by a signal */
597 if (PyErr_CheckSignals()) {
598 async_err = 1;
599 break;
600 }
601
602 if (timeout >= 0) {
603 timeout = deadline - _PyTime_GetMonotonicClock();
604 if (timeout < 0) {
605 poll_result = 0;
606 break;
607 }
608 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
609 /* retry poll() with the recomputed timeout */
610 }
611 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000612
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300613 self->poll_running = 0;
614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200616 if (!async_err)
617 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 return NULL;
619 }
620
621 /* build the result list */
622
623 result_list = PyList_New(poll_result);
624 if (!result_list)
625 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200627 for (i = 0, j = 0; j < poll_result; j++) {
628 /* skip to the next fired descriptor */
629 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 i++;
631 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200632 /* if we hit a NULL return, set value to NULL
633 and break out of loop; code at end will
634 clean up result_list */
635 value = PyTuple_New(2);
636 if (value == NULL)
637 goto error;
638 num = PyLong_FromLong(self->ufds[i].fd);
639 if (num == NULL) {
640 Py_DECREF(value);
641 goto error;
642 }
643 PyTuple_SET_ITEM(value, 0, num);
644
645 /* The &0xffff is a workaround for AIX. 'revents'
646 is a 16-bit short, and IBM assigned POLLNVAL
647 to be 0x8000, so the conversion to int results
648 in a negative number. See SF bug #923315. */
649 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
650 if (num == NULL) {
651 Py_DECREF(value);
652 goto error;
653 }
654 PyTuple_SET_ITEM(value, 1, num);
Miss Islington (bot)8b7d8ac2018-12-08 06:34:49 -0800655 PyList_SET_ITEM(result_list, j, value);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200656 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 }
658 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000659
660 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 Py_DECREF(result_list);
662 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000663}
664
665static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 {"register", (PyCFunction)poll_register,
667 METH_VARARGS, poll_register_doc},
668 {"modify", (PyCFunction)poll_modify,
669 METH_VARARGS, poll_modify_doc},
670 {"unregister", (PyCFunction)poll_unregister,
671 METH_O, poll_unregister_doc},
672 {"poll", (PyCFunction)poll_poll,
673 METH_VARARGS, poll_poll_doc},
674 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000675};
676
677static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000678newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 pollObject *self;
681 self = PyObject_New(pollObject, &poll_Type);
682 if (self == NULL)
683 return NULL;
684 /* ufd_uptodate is a Boolean, denoting whether the
685 array pointed to by ufds matches the contents of the dictionary. */
686 self->ufd_uptodate = 0;
687 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300688 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 self->dict = PyDict_New();
690 if (self->dict == NULL) {
691 Py_DECREF(self);
692 return NULL;
693 }
694 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000695}
696
697static void
698poll_dealloc(pollObject *self)
699{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 if (self->ufds != NULL)
701 PyMem_DEL(self->ufds);
702 Py_XDECREF(self->dict);
703 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000704}
705
Tim Peters0c322792002-07-17 16:49:03 +0000706static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 /* The ob_type field must be initialized in the module init function
708 * to be portable to Windows without using C++. */
709 PyVarObject_HEAD_INIT(NULL, 0)
710 "select.poll", /*tp_name*/
711 sizeof(pollObject), /*tp_basicsize*/
712 0, /*tp_itemsize*/
713 /* methods */
714 (destructor)poll_dealloc, /*tp_dealloc*/
715 0, /*tp_print*/
716 0, /*tp_getattr*/
717 0, /*tp_setattr*/
718 0, /*tp_reserved*/
719 0, /*tp_repr*/
720 0, /*tp_as_number*/
721 0, /*tp_as_sequence*/
722 0, /*tp_as_mapping*/
723 0, /*tp_hash*/
724 0, /*tp_call*/
725 0, /*tp_str*/
726 0, /*tp_getattro*/
727 0, /*tp_setattro*/
728 0, /*tp_as_buffer*/
729 Py_TPFLAGS_DEFAULT, /*tp_flags*/
730 0, /*tp_doc*/
731 0, /*tp_traverse*/
732 0, /*tp_clear*/
733 0, /*tp_richcompare*/
734 0, /*tp_weaklistoffset*/
735 0, /*tp_iter*/
736 0, /*tp_iternext*/
737 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000738};
739
Jesus Cead8b9ae62011-11-14 19:07:41 +0100740#ifdef HAVE_SYS_DEVPOLL_H
741typedef struct {
742 PyObject_HEAD
743 int fd_devpoll;
744 int max_n_fds;
745 int n_fds;
746 struct pollfd *fds;
747} devpollObject;
748
749static PyTypeObject devpoll_Type;
750
Victor Stinner13423c32013-08-22 00:19:50 +0200751static PyObject *
752devpoll_err_closed(void)
753{
754 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
755 return NULL;
756}
757
Jesus Cead8b9ae62011-11-14 19:07:41 +0100758static int devpoll_flush(devpollObject *self)
759{
760 int size, n;
761
762 if (!self->n_fds) return 0;
763
764 size = sizeof(struct pollfd)*self->n_fds;
765 self->n_fds = 0;
766
Victor Stinner54799672015-03-19 23:33:09 +0100767 n = _Py_write(self->fd_devpoll, self->fds, size);
768 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100769 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100770
Jesus Cead8b9ae62011-11-14 19:07:41 +0100771 if (n < size) {
772 /*
773 ** Data writed to /dev/poll is a binary data structure. It is not
774 ** clear what to do if a partial write occurred. For now, raise
775 ** an exception and see if we actually found this problem in
776 ** the wild.
777 ** See http://bugs.python.org/issue6397.
778 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300779 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100780 "Please, report at http://bugs.python.org/. "
781 "Data to report: Size tried: %d, actual size written: %d.",
782 size, n);
783 return -1;
784 }
785 return 0;
786}
787
788static PyObject *
789internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
790{
791 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200792 int fd;
793 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100794
Victor Stinner13423c32013-08-22 00:19:50 +0200795 if (self->fd_devpoll < 0)
796 return devpoll_err_closed();
797
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200798 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100799 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100800
801 fd = PyObject_AsFileDescriptor(o);
802 if (fd == -1) return NULL;
803
804 if (remove) {
805 self->fds[self->n_fds].fd = fd;
806 self->fds[self->n_fds].events = POLLREMOVE;
807
808 if (++self->n_fds == self->max_n_fds) {
809 if (devpoll_flush(self))
810 return NULL;
811 }
812 }
813
814 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200815 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100816
817 if (++self->n_fds == self->max_n_fds) {
818 if (devpoll_flush(self))
819 return NULL;
820 }
821
822 Py_RETURN_NONE;
823}
824
825PyDoc_STRVAR(devpoll_register_doc,
826"register(fd [, eventmask] ) -> None\n\n\
827Register a file descriptor with the polling object.\n\
828fd -- either an integer, or an object with a fileno() method returning an\n\
829 int.\n\
830events -- an optional bitmask describing the type of events to check for");
831
832static PyObject *
833devpoll_register(devpollObject *self, PyObject *args)
834{
835 return internal_devpoll_register(self, args, 0);
836}
837
838PyDoc_STRVAR(devpoll_modify_doc,
839"modify(fd[, eventmask]) -> None\n\n\
840Modify a possible already registered file descriptor.\n\
841fd -- either an integer, or an object with a fileno() method returning an\n\
842 int.\n\
843events -- an optional bitmask describing the type of events to check for");
844
845static PyObject *
846devpoll_modify(devpollObject *self, PyObject *args)
847{
848 return internal_devpoll_register(self, args, 1);
849}
850
851
852PyDoc_STRVAR(devpoll_unregister_doc,
853"unregister(fd) -> None\n\n\
854Remove a file descriptor being tracked by the polling object.");
855
856static PyObject *
857devpoll_unregister(devpollObject *self, PyObject *o)
858{
859 int fd;
860
Victor Stinner13423c32013-08-22 00:19:50 +0200861 if (self->fd_devpoll < 0)
862 return devpoll_err_closed();
863
Jesus Cead8b9ae62011-11-14 19:07:41 +0100864 fd = PyObject_AsFileDescriptor( o );
865 if (fd == -1)
866 return NULL;
867
868 self->fds[self->n_fds].fd = fd;
869 self->fds[self->n_fds].events = POLLREMOVE;
870
871 if (++self->n_fds == self->max_n_fds) {
872 if (devpoll_flush(self))
873 return NULL;
874 }
875
876 Py_RETURN_NONE;
877}
878
879PyDoc_STRVAR(devpoll_poll_doc,
880"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
881Polls the set of registered file descriptors, returning a list containing \n\
882any descriptors that have events or errors to report.");
883
884static PyObject *
885devpoll_poll(devpollObject *self, PyObject *args)
886{
887 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200888 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100889 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100890 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200891 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100892
Victor Stinner13423c32013-08-22 00:19:50 +0200893 if (self->fd_devpoll < 0)
894 return devpoll_err_closed();
895
Victor Stinner45ca48b2015-03-31 12:10:33 +0200896 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100897 return NULL;
898 }
899
900 /* Check values for timeout */
Victor Stinner45ca48b2015-03-31 12:10:33 +0200901 if (timeout_obj == NULL || timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100902 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200903 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100904 }
905 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200906 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100907 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200908 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
909 PyErr_SetString(PyExc_TypeError,
910 "timeout must be an integer or None");
911 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200913 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100914
Pablo Galindo2c15b292017-10-17 15:14:41 +0100915 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200916 if (ms < -1 || ms > INT_MAX) {
917 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
918 return NULL;
919 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920 }
921
922 if (devpoll_flush(self))
923 return NULL;
924
925 dvp.dp_fds = self->fds;
926 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200927 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100928
Victor Stinner45ca48b2015-03-31 12:10:33 +0200929 if (timeout >= 0)
930 deadline = _PyTime_GetMonotonicClock() + timeout;
931
932 do {
933 /* call devpoll() */
934 Py_BEGIN_ALLOW_THREADS
935 errno = 0;
936 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
937 Py_END_ALLOW_THREADS
938
939 if (errno != EINTR)
940 break;
941
942 /* devpoll() was interrupted by a signal */
943 if (PyErr_CheckSignals())
944 return NULL;
945
946 if (timeout >= 0) {
947 timeout = deadline - _PyTime_GetMonotonicClock();
948 if (timeout < 0) {
949 poll_result = 0;
950 break;
951 }
952 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
953 dvp.dp_timeout = (int)ms;
954 /* retry devpoll() with the recomputed timeout */
955 }
956 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100957
958 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300959 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100960 return NULL;
961 }
962
963 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100964 result_list = PyList_New(poll_result);
965 if (!result_list)
966 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200967
968 for (i = 0; i < poll_result; i++) {
969 num1 = PyLong_FromLong(self->fds[i].fd);
970 num2 = PyLong_FromLong(self->fds[i].revents);
971 if ((num1 == NULL) || (num2 == NULL)) {
972 Py_XDECREF(num1);
973 Py_XDECREF(num2);
974 goto error;
975 }
976 value = PyTuple_Pack(2, num1, num2);
977 Py_DECREF(num1);
978 Py_DECREF(num2);
979 if (value == NULL)
980 goto error;
Miss Islington (bot)8b7d8ac2018-12-08 06:34:49 -0800981 PyList_SET_ITEM(result_list, i, value);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100982 }
983
984 return result_list;
985
986 error:
987 Py_DECREF(result_list);
988 return NULL;
989}
990
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100991static int
992devpoll_internal_close(devpollObject *self)
993{
994 int save_errno = 0;
995 if (self->fd_devpoll >= 0) {
996 int fd = self->fd_devpoll;
997 self->fd_devpoll = -1;
998 Py_BEGIN_ALLOW_THREADS
999 if (close(fd) < 0)
1000 save_errno = errno;
1001 Py_END_ALLOW_THREADS
1002 }
1003 return save_errno;
1004}
1005
Victor Stinner13423c32013-08-22 00:19:50 +02001006static PyObject*
1007devpoll_close(devpollObject *self)
1008{
1009 errno = devpoll_internal_close(self);
1010 if (errno < 0) {
1011 PyErr_SetFromErrno(PyExc_OSError);
1012 return NULL;
1013 }
1014 Py_RETURN_NONE;
1015}
1016
1017PyDoc_STRVAR(devpoll_close_doc,
1018"close() -> None\n\
1019\n\
1020Close the devpoll file descriptor. Further operations on the devpoll\n\
1021object will raise an exception.");
1022
1023static PyObject*
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001024devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored))
Victor Stinner13423c32013-08-22 00:19:50 +02001025{
1026 if (self->fd_devpoll < 0)
1027 Py_RETURN_TRUE;
1028 else
1029 Py_RETURN_FALSE;
1030}
1031
1032static PyObject*
1033devpoll_fileno(devpollObject *self)
1034{
1035 if (self->fd_devpoll < 0)
1036 return devpoll_err_closed();
1037 return PyLong_FromLong(self->fd_devpoll);
1038}
1039
1040PyDoc_STRVAR(devpoll_fileno_doc,
1041"fileno() -> int\n\
1042\n\
1043Return the file descriptor.");
1044
Jesus Cead8b9ae62011-11-14 19:07:41 +01001045static PyMethodDef devpoll_methods[] = {
1046 {"register", (PyCFunction)devpoll_register,
1047 METH_VARARGS, devpoll_register_doc},
1048 {"modify", (PyCFunction)devpoll_modify,
1049 METH_VARARGS, devpoll_modify_doc},
1050 {"unregister", (PyCFunction)devpoll_unregister,
1051 METH_O, devpoll_unregister_doc},
1052 {"poll", (PyCFunction)devpoll_poll,
1053 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +02001054 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
1055 devpoll_close_doc},
1056 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
1057 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +01001058 {NULL, NULL} /* sentinel */
1059};
1060
Victor Stinner13423c32013-08-22 00:19:50 +02001061static PyGetSetDef devpoll_getsetlist[] = {
1062 {"closed", (getter)devpoll_get_closed, NULL,
1063 "True if the devpoll object is closed"},
1064 {0},
1065};
1066
Jesus Cead8b9ae62011-11-14 19:07:41 +01001067static devpollObject *
1068newDevPollObject(void)
1069{
1070 devpollObject *self;
1071 int fd_devpoll, limit_result;
1072 struct pollfd *fds;
1073 struct rlimit limit;
1074
Jesus Cead8b9ae62011-11-14 19:07:41 +01001075 /*
1076 ** If we try to process more that getrlimit()
1077 ** fds, the kernel will give an error, so
1078 ** we set the limit here. It is a dynamic
1079 ** value, because we can change rlimit() anytime.
1080 */
1081 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001082 if (limit_result == -1) {
1083 PyErr_SetFromErrno(PyExc_OSError);
1084 return NULL;
1085 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001086
1087 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1088 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001089 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001090
1091 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1092 if (fds == NULL) {
1093 close(fd_devpoll);
1094 PyErr_NoMemory();
1095 return NULL;
1096 }
1097
1098 self = PyObject_New(devpollObject, &devpoll_Type);
1099 if (self == NULL) {
1100 close(fd_devpoll);
1101 PyMem_DEL(fds);
1102 return NULL;
1103 }
1104 self->fd_devpoll = fd_devpoll;
1105 self->max_n_fds = limit.rlim_cur;
1106 self->n_fds = 0;
1107 self->fds = fds;
1108
1109 return self;
1110}
1111
1112static void
1113devpoll_dealloc(devpollObject *self)
1114{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001115 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001116 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001117 PyObject_Del(self);
1118}
1119
1120static PyTypeObject devpoll_Type = {
1121 /* The ob_type field must be initialized in the module init function
1122 * to be portable to Windows without using C++. */
1123 PyVarObject_HEAD_INIT(NULL, 0)
1124 "select.devpoll", /*tp_name*/
1125 sizeof(devpollObject), /*tp_basicsize*/
1126 0, /*tp_itemsize*/
1127 /* methods */
1128 (destructor)devpoll_dealloc, /*tp_dealloc*/
1129 0, /*tp_print*/
1130 0, /*tp_getattr*/
1131 0, /*tp_setattr*/
1132 0, /*tp_reserved*/
1133 0, /*tp_repr*/
1134 0, /*tp_as_number*/
1135 0, /*tp_as_sequence*/
1136 0, /*tp_as_mapping*/
1137 0, /*tp_hash*/
1138 0, /*tp_call*/
1139 0, /*tp_str*/
1140 0, /*tp_getattro*/
1141 0, /*tp_setattro*/
1142 0, /*tp_as_buffer*/
1143 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1144 0, /*tp_doc*/
1145 0, /*tp_traverse*/
1146 0, /*tp_clear*/
1147 0, /*tp_richcompare*/
1148 0, /*tp_weaklistoffset*/
1149 0, /*tp_iter*/
1150 0, /*tp_iternext*/
1151 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001152 0, /* tp_members */
1153 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001154};
1155#endif /* HAVE_SYS_DEVPOLL_H */
1156
1157
1158
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001159PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001160"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001161unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001162
1163static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001164select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001167}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001168
Jesus Cead8b9ae62011-11-14 19:07:41 +01001169#ifdef HAVE_SYS_DEVPOLL_H
1170PyDoc_STRVAR(devpoll_doc,
1171"Returns a polling object, which supports registering and\n\
1172unregistering file descriptors, and then polling them for I/O events.");
1173
1174static PyObject *
1175select_devpoll(PyObject *self, PyObject *unused)
1176{
1177 return (PyObject *)newDevPollObject();
1178}
1179#endif
1180
1181
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184 * On some systems poll() sets errno on invalid file descriptors. We test
1185 * for this at runtime because this bug may be fixed or introduced between
1186 * OS releases.
1187 */
1188static int select_have_broken_poll(void)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 int poll_test;
1191 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 /* Create a file descriptor to make invalid */
1196 if (pipe(filedes) < 0) {
1197 return 1;
1198 }
1199 poll_struct.fd = filedes[0];
1200 close(filedes[0]);
1201 close(filedes[1]);
1202 poll_test = poll(&poll_struct, 1, 0);
1203 if (poll_test < 0) {
1204 return 1;
1205 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1206 return 1;
1207 }
1208 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001209}
1210#endif /* __APPLE__ */
1211
1212#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001213
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001214#ifdef HAVE_EPOLL
1215/* **************************************************************************
1216 * epoll interface for Linux 2.6
1217 *
1218 * Written by Christian Heimes
1219 * Inspired by Twisted's _epoll.pyx and select.poll()
1220 */
1221
1222#ifdef HAVE_SYS_EPOLL_H
1223#include <sys/epoll.h>
1224#endif
1225
1226typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001228 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001229} pyEpoll_Object;
1230
1231static PyTypeObject pyEpoll_Type;
1232#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1233
1234static PyObject *
1235pyepoll_err_closed(void)
1236{
Victor Stinner13423c32013-08-22 00:19:50 +02001237 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001239}
1240
1241static int
1242pyepoll_internal_close(pyEpoll_Object *self)
1243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 int save_errno = 0;
1245 if (self->epfd >= 0) {
1246 int epfd = self->epfd;
1247 self->epfd = -1;
1248 Py_BEGIN_ALLOW_THREADS
1249 if (close(epfd) < 0)
1250 save_errno = errno;
1251 Py_END_ALLOW_THREADS
1252 }
1253 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001254}
1255
1256static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001257newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 assert(type != NULL && type->tp_alloc != NULL);
1262 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1263 if (self == NULL)
1264 return NULL;
1265
1266 if (fd == -1) {
1267 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001268#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001269 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1270#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001271 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001272#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 Py_END_ALLOW_THREADS
1274 }
1275 else {
1276 self->epfd = fd;
1277 }
1278 if (self->epfd < 0) {
1279 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001280 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 return NULL;
1282 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001283
1284#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001285 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001286 Py_DECREF(self);
1287 return NULL;
1288 }
1289#endif
1290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001292}
1293
1294
1295static PyObject *
1296pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1297{
Miss Islington (bot)fd1c0922018-06-30 06:03:19 -07001298 int flags = 0, sizehint = -1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001299 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001300
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001301 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1302 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 return NULL;
Miss Islington (bot)fd1c0922018-06-30 06:03:19 -07001304 if (sizehint == -1) {
1305 sizehint = FD_SETSIZE - 1;
1306 }
1307 else if (sizehint <= 0) {
1308 PyErr_SetString(PyExc_ValueError, "sizehint must be positive or -1");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001309 return NULL;
1310 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001311
1312#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001313 if (flags && flags != EPOLL_CLOEXEC) {
1314 PyErr_SetString(PyExc_OSError, "invalid flags");
1315 return NULL;
1316 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001317#endif
Berker Peksage2197d12016-09-26 23:30:41 +03001318 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001319}
1320
1321
1322static void
1323pyepoll_dealloc(pyEpoll_Object *self)
1324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 (void)pyepoll_internal_close(self);
1326 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001327}
1328
1329static PyObject*
1330pyepoll_close(pyEpoll_Object *self)
1331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 errno = pyepoll_internal_close(self);
1333 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001334 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 return NULL;
1336 }
1337 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001338}
1339
1340PyDoc_STRVAR(pyepoll_close_doc,
1341"close() -> None\n\
1342\n\
1343Close the epoll control file descriptor. Further operations on the epoll\n\
1344object will raise an exception.");
1345
1346static PyObject*
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08001347pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 if (self->epfd < 0)
1350 Py_RETURN_TRUE;
1351 else
1352 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001353}
1354
1355static PyObject*
1356pyepoll_fileno(pyEpoll_Object *self)
1357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 if (self->epfd < 0)
1359 return pyepoll_err_closed();
1360 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001361}
1362
1363PyDoc_STRVAR(pyepoll_fileno_doc,
1364"fileno() -> int\n\
1365\n\
1366Return the epoll control file descriptor.");
1367
1368static PyObject*
1369pyepoll_fromfd(PyObject *cls, PyObject *args)
1370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1374 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001375
Berker Peksage2197d12016-09-26 23:30:41 +03001376 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377}
1378
1379PyDoc_STRVAR(pyepoll_fromfd_doc,
1380"fromfd(fd) -> epoll\n\
1381\n\
1382Create an epoll object from a given control fd.");
1383
1384static PyObject *
1385pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 struct epoll_event ev;
1388 int result;
1389 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (epfd < 0)
1392 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 fd = PyObject_AsFileDescriptor(pfd);
1395 if (fd == -1) {
1396 return NULL;
1397 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001398
Guido van Rossumee07b942013-12-06 17:46:22 -08001399 switch (op) {
1400 case EPOLL_CTL_ADD:
1401 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 ev.events = events;
1403 ev.data.fd = fd;
1404 Py_BEGIN_ALLOW_THREADS
1405 result = epoll_ctl(epfd, op, fd, &ev);
1406 Py_END_ALLOW_THREADS
1407 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001408 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1410 * operation required a non-NULL pointer in event, even
1411 * though this argument is ignored. */
1412 Py_BEGIN_ALLOW_THREADS
1413 result = epoll_ctl(epfd, op, fd, &ev);
1414 if (errno == EBADF) {
1415 /* fd already closed */
1416 result = 0;
1417 errno = 0;
1418 }
1419 Py_END_ALLOW_THREADS
1420 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001421 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 result = -1;
1423 errno = EINVAL;
1424 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001427 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 return NULL;
1429 }
1430 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001431}
1432
1433static PyObject *
1434pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 PyObject *pfd;
1437 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1438 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1441 &pfd, &events)) {
1442 return NULL;
1443 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446}
1447
1448PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001449"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001450\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001451Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001452fd is the target file descriptor of the operation.\n\
1453events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001454is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455\n\
1456The epoll interface supports all file descriptors that support poll.");
1457
1458static PyObject *
1459pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 PyObject *pfd;
1462 unsigned int events;
1463 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1466 &pfd, &events)) {
1467 return NULL;
1468 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471}
1472
1473PyDoc_STRVAR(pyepoll_modify_doc,
1474"modify(fd, eventmask) -> None\n\
1475\n\
1476fd is the target file descriptor of the operation\n\
1477events is a bit set composed of the various EPOLL constants");
1478
1479static PyObject *
1480pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 PyObject *pfd;
1483 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1486 &pfd)) {
1487 return NULL;
1488 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001491}
1492
1493PyDoc_STRVAR(pyepoll_unregister_doc,
1494"unregister(fd) -> None\n\
1495\n\
1496fd is the target file descriptor of the operation.");
1497
1498static PyObject *
1499pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1500{
Victor Stinner41eba222015-03-30 21:59:21 +02001501 static char *kwlist[] = {"timeout", "maxevents", NULL};
1502 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 int maxevents = -1;
1504 int nfds, i;
1505 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001506 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001507 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 if (self->epfd < 0)
1510 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511
Victor Stinner41eba222015-03-30 21:59:21 +02001512 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1513 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 return NULL;
1515 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001516
Victor Stinner41eba222015-03-30 21:59:21 +02001517 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001519 ms = -1;
1520 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 }
1522 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001523 /* epoll_wait() has a resolution of 1 millisecond, round towards
1524 infinity to wait at least timeout seconds. */
1525 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001526 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001527 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1528 PyErr_SetString(PyExc_TypeError,
1529 "timeout must be an integer or None");
1530 }
1531 return NULL;
1532 }
1533
1534 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1535 if (ms < INT_MIN || ms > INT_MAX) {
1536 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1537 return NULL;
1538 }
1539
1540 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001544 maxevents = FD_SETSIZE-1;
1545 }
1546 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 PyErr_Format(PyExc_ValueError,
1548 "maxevents must be greater than 0, got %d",
1549 maxevents);
1550 return NULL;
1551 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001552
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001553 evs = PyMem_New(struct epoll_event, maxevents);
1554 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001555 PyErr_NoMemory();
1556 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001558
Victor Stinner41eba222015-03-30 21:59:21 +02001559 do {
1560 Py_BEGIN_ALLOW_THREADS
1561 errno = 0;
1562 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1563 Py_END_ALLOW_THREADS
1564
1565 if (errno != EINTR)
1566 break;
1567
1568 /* poll() was interrupted by a signal */
1569 if (PyErr_CheckSignals())
1570 goto error;
1571
1572 if (timeout >= 0) {
1573 timeout = deadline - _PyTime_GetMonotonicClock();
1574 if (timeout < 0) {
1575 nfds = 0;
1576 break;
1577 }
1578 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1579 /* retry epoll_wait() with the recomputed timeout */
1580 }
1581 } while(1);
1582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001584 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 goto error;
1586 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 elist = PyList_New(nfds);
1589 if (elist == NULL) {
1590 goto error;
1591 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001594 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (etuple == NULL) {
1596 Py_CLEAR(elist);
1597 goto error;
1598 }
1599 PyList_SET_ITEM(elist, i, etuple);
1600 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001601
Christian Heimesf6cd9672008-03-26 13:45:42 +00001602 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001603 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001605}
1606
1607PyDoc_STRVAR(pyepoll_poll_doc,
1608"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1609\n\
1610Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1611in seconds (as float). -1 makes poll wait indefinitely.\n\
1612Up to maxevents are returned to the caller.");
1613
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001614static PyObject *
1615pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1616{
1617 if (self->epfd < 0)
1618 return pyepoll_err_closed();
1619
1620 Py_INCREF(self);
1621 return (PyObject *)self;
1622}
1623
1624static PyObject *
1625pyepoll_exit(PyObject *self, PyObject *args)
1626{
1627 _Py_IDENTIFIER(close);
1628
1629 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1630}
1631
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001632static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 {"fromfd", (PyCFunction)pyepoll_fromfd,
1634 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1635 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1636 pyepoll_close_doc},
1637 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1638 pyepoll_fileno_doc},
1639 {"modify", (PyCFunction)pyepoll_modify,
1640 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1641 {"register", (PyCFunction)pyepoll_register,
1642 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1643 {"unregister", (PyCFunction)pyepoll_unregister,
1644 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1645 {"poll", (PyCFunction)pyepoll_poll,
1646 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001647 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1648 NULL},
1649 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1650 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652};
1653
1654static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 {"closed", (getter)pyepoll_get_closed, NULL,
1656 "True if the epoll handler is closed"},
1657 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001658};
1659
1660PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001661"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001662\n\
1663Returns an epolling object\n\
1664\n\
1665sizehint must be a positive integer or -1 for the default size. The\n\
1666sizehint is used to optimize internal data structures. It doesn't limit\n\
1667the maximum number of monitored events.");
1668
1669static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 PyVarObject_HEAD_INIT(NULL, 0)
1671 "select.epoll", /* tp_name */
1672 sizeof(pyEpoll_Object), /* tp_basicsize */
1673 0, /* tp_itemsize */
1674 (destructor)pyepoll_dealloc, /* tp_dealloc */
1675 0, /* tp_print */
1676 0, /* tp_getattr */
1677 0, /* tp_setattr */
1678 0, /* tp_reserved */
1679 0, /* tp_repr */
1680 0, /* tp_as_number */
1681 0, /* tp_as_sequence */
1682 0, /* tp_as_mapping */
1683 0, /* tp_hash */
1684 0, /* tp_call */
1685 0, /* tp_str */
1686 PyObject_GenericGetAttr, /* tp_getattro */
1687 0, /* tp_setattro */
1688 0, /* tp_as_buffer */
1689 Py_TPFLAGS_DEFAULT, /* tp_flags */
1690 pyepoll_doc, /* tp_doc */
1691 0, /* tp_traverse */
1692 0, /* tp_clear */
1693 0, /* tp_richcompare */
1694 0, /* tp_weaklistoffset */
1695 0, /* tp_iter */
1696 0, /* tp_iternext */
1697 pyepoll_methods, /* tp_methods */
1698 0, /* tp_members */
1699 pyepoll_getsetlist, /* tp_getset */
1700 0, /* tp_base */
1701 0, /* tp_dict */
1702 0, /* tp_descr_get */
1703 0, /* tp_descr_set */
1704 0, /* tp_dictoffset */
1705 0, /* tp_init */
1706 0, /* tp_alloc */
1707 pyepoll_new, /* tp_new */
1708 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001709};
1710
1711#endif /* HAVE_EPOLL */
1712
1713#ifdef HAVE_KQUEUE
1714/* **************************************************************************
1715 * kqueue interface for BSD
1716 *
1717 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1718 * All rights reserved.
1719 *
1720 * Redistribution and use in source and binary forms, with or without
1721 * modification, are permitted provided that the following conditions
1722 * are met:
1723 * 1. Redistributions of source code must retain the above copyright
1724 * notice, this list of conditions and the following disclaimer.
1725 * 2. Redistributions in binary form must reproduce the above copyright
1726 * notice, this list of conditions and the following disclaimer in the
1727 * documentation and/or other materials provided with the distribution.
1728 *
1729 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1730 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1731 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1732 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1733 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1734 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1735 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1736 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1737 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1738 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1739 * SUCH DAMAGE.
1740 */
1741
1742#ifdef HAVE_SYS_EVENT_H
1743#include <sys/event.h>
1744#endif
1745
1746PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001747"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001748\n\
1749This object is the equivalent of the struct kevent for the C API.\n\
1750\n\
1751See the kqueue manpage for more detailed information about the meaning\n\
1752of the arguments.\n\
1753\n\
1754One minor note: while you might hope that udata could store a\n\
1755reference to a python object, it cannot, because it is impossible to\n\
1756keep a proper reference count of the object once it's passed into the\n\
1757kernel. Therefore, I have restricted it to only storing an integer. I\n\
1758recommend ignoring it and simply using the 'ident' field to key off\n\
1759of. You could also set up a dictionary on the python side to store a\n\
1760udata->object mapping.");
1761
1762typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 PyObject_HEAD
1764 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001765} kqueue_event_Object;
1766
1767static PyTypeObject kqueue_event_Type;
1768
1769#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1770
1771typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 PyObject_HEAD
1773 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001774} kqueue_queue_Object;
1775
1776static PyTypeObject kqueue_queue_Type;
1777
1778#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1779
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001780#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1781# error uintptr_t does not match void *!
1782#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1783# define T_UINTPTRT T_ULONGLONG
1784# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001785# define UINTPTRT_FMT_UNIT "K"
1786# define INTPTRT_FMT_UNIT "L"
1787#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1788# define T_UINTPTRT T_ULONG
1789# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001790# define UINTPTRT_FMT_UNIT "k"
1791# define INTPTRT_FMT_UNIT "l"
1792#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1793# define T_UINTPTRT T_UINT
1794# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001795# define UINTPTRT_FMT_UNIT "I"
1796# define INTPTRT_FMT_UNIT "i"
1797#else
1798# error uintptr_t does not match int, long, or long long!
1799#endif
1800
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001801#if SIZEOF_LONG_LONG == 8
1802# define T_INT64 T_LONGLONG
1803# define INT64_FMT_UNIT "L"
1804#elif SIZEOF_LONG == 8
1805# define T_INT64 T_LONG
1806# define INT64_FMT_UNIT "l"
1807#elif SIZEOF_INT == 8
1808# define T_INT64 T_INT
1809# define INT64_FMT_UNIT "i"
1810#else
1811# define INT64_FMT_UNIT "_"
1812#endif
1813
1814#if SIZEOF_LONG_LONG == 4
1815# define T_UINT32 T_ULONGLONG
1816# define UINT32_FMT_UNIT "K"
1817#elif SIZEOF_LONG == 4
1818# define T_UINT32 T_ULONG
1819# define UINT32_FMT_UNIT "k"
1820#elif SIZEOF_INT == 4
1821# define T_UINT32 T_UINT
1822# define UINT32_FMT_UNIT "I"
1823#else
1824# define UINT32_FMT_UNIT "_"
1825#endif
1826
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001827/*
1828 * kevent is not standard and its members vary across BSDs.
1829 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001830#ifdef __NetBSD__
1831# define FILTER_TYPE T_UINT32
1832# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1833# define FLAGS_TYPE T_UINT32
1834# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1835# define FFLAGS_TYPE T_UINT32
1836# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001837#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001838# define FILTER_TYPE T_SHORT
1839# define FILTER_FMT_UNIT "h"
1840# define FLAGS_TYPE T_USHORT
1841# define FLAGS_FMT_UNIT "H"
1842# define FFLAGS_TYPE T_UINT
1843# define FFLAGS_FMT_UNIT "I"
1844#endif
1845
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001846#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001847# define DATA_TYPE T_INT64
1848# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001849#else
1850# define DATA_TYPE T_INTPTRT
1851# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001852#endif
1853
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001854/* Unfortunately, we can't store python objects in udata, because
1855 * kevents in the kernel can be removed without warning, which would
1856 * forever lose the refcount on the object stored with it.
1857 */
1858
1859#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1860static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001861 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1862 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1863 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001865 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1867 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001868};
1869#undef KQ_OFF
1870
1871static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001872
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873kqueue_event_repr(kqueue_event_Object *s)
1874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 char buf[1024];
1876 PyOS_snprintf(
1877 buf, sizeof(buf),
1878 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001879 "data=0x%llx udata=%p>",
1880 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1881 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001883}
1884
1885static int
1886kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 PyObject *pfd;
1889 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1890 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001891 static const char fmt[] = "O|"
1892 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1893 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1898 &pfd, &(self->e.filter), &(self->e.flags),
1899 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1900 return -1;
1901 }
1902
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001903 if (PyLong_Check(pfd)) {
1904 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 }
1906 else {
1907 self->e.ident = PyObject_AsFileDescriptor(pfd);
1908 }
1909 if (PyErr_Occurred()) {
1910 return -1;
1911 }
1912 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001913}
1914
1915static PyObject *
1916kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001918{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001919 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001922 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001924
1925#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1926 result = CMP(s->e.ident, o->e.ident)
1927 : CMP(s->e.filter, o->e.filter)
1928 : CMP(s->e.flags, o->e.flags)
1929 : CMP(s->e.fflags, o->e.fflags)
1930 : CMP(s->e.data, o->e.data)
1931 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1932 : 0;
1933#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001934
stratakise8b19652017-11-02 11:32:54 +01001935 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001936}
1937
1938static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 PyVarObject_HEAD_INIT(NULL, 0)
1940 "select.kevent", /* tp_name */
1941 sizeof(kqueue_event_Object), /* tp_basicsize */
1942 0, /* tp_itemsize */
1943 0, /* tp_dealloc */
1944 0, /* tp_print */
1945 0, /* tp_getattr */
1946 0, /* tp_setattr */
1947 0, /* tp_reserved */
1948 (reprfunc)kqueue_event_repr, /* tp_repr */
1949 0, /* tp_as_number */
1950 0, /* tp_as_sequence */
1951 0, /* tp_as_mapping */
1952 0, /* tp_hash */
1953 0, /* tp_call */
1954 0, /* tp_str */
1955 0, /* tp_getattro */
1956 0, /* tp_setattro */
1957 0, /* tp_as_buffer */
1958 Py_TPFLAGS_DEFAULT, /* tp_flags */
1959 kqueue_event_doc, /* tp_doc */
1960 0, /* tp_traverse */
1961 0, /* tp_clear */
1962 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1963 0, /* tp_weaklistoffset */
1964 0, /* tp_iter */
1965 0, /* tp_iternext */
1966 0, /* tp_methods */
1967 kqueue_event_members, /* tp_members */
1968 0, /* tp_getset */
1969 0, /* tp_base */
1970 0, /* tp_dict */
1971 0, /* tp_descr_get */
1972 0, /* tp_descr_set */
1973 0, /* tp_dictoffset */
1974 (initproc)kqueue_event_init, /* tp_init */
1975 0, /* tp_alloc */
1976 0, /* tp_new */
1977 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001978};
1979
1980static PyObject *
1981kqueue_queue_err_closed(void)
1982{
Victor Stinner13423c32013-08-22 00:19:50 +02001983 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001985}
1986
1987static int
1988kqueue_queue_internal_close(kqueue_queue_Object *self)
1989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 int save_errno = 0;
1991 if (self->kqfd >= 0) {
1992 int kqfd = self->kqfd;
1993 self->kqfd = -1;
1994 Py_BEGIN_ALLOW_THREADS
1995 if (close(kqfd) < 0)
1996 save_errno = errno;
1997 Py_END_ALLOW_THREADS
1998 }
1999 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002000}
2001
2002static PyObject *
2003newKqueue_Object(PyTypeObject *type, SOCKET fd)
2004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 kqueue_queue_Object *self;
2006 assert(type != NULL && type->tp_alloc != NULL);
2007 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
2008 if (self == NULL) {
2009 return NULL;
2010 }
2011
2012 if (fd == -1) {
2013 Py_BEGIN_ALLOW_THREADS
2014 self->kqfd = kqueue();
2015 Py_END_ALLOW_THREADS
2016 }
2017 else {
2018 self->kqfd = fd;
2019 }
2020 if (self->kqfd < 0) {
2021 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002022 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 return NULL;
2024 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002025
2026 if (fd == -1) {
2027 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2028 Py_DECREF(self);
2029 return NULL;
2030 }
2031 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033}
2034
2035static PyObject *
2036kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2037{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002038 if (PyTuple_GET_SIZE(args) ||
2039 (kwds != NULL && PyDict_GET_SIZE(kwds))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 PyErr_SetString(PyExc_ValueError,
2041 "select.kqueue doesn't accept arguments");
2042 return NULL;
2043 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002046}
2047
2048static void
2049kqueue_queue_dealloc(kqueue_queue_Object *self)
2050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 kqueue_queue_internal_close(self);
2052 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002053}
2054
2055static PyObject*
2056kqueue_queue_close(kqueue_queue_Object *self)
2057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 errno = kqueue_queue_internal_close(self);
2059 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002060 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 return NULL;
2062 }
2063 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002064}
2065
2066PyDoc_STRVAR(kqueue_queue_close_doc,
2067"close() -> None\n\
2068\n\
2069Close the kqueue control file descriptor. Further operations on the kqueue\n\
2070object will raise an exception.");
2071
2072static PyObject*
Miss Islington (bot)5ceb7012018-11-27 09:58:07 -08002073kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored))
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 if (self->kqfd < 0)
2076 Py_RETURN_TRUE;
2077 else
2078 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002079}
2080
2081static PyObject*
2082kqueue_queue_fileno(kqueue_queue_Object *self)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 if (self->kqfd < 0)
2085 return kqueue_queue_err_closed();
2086 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002087}
2088
2089PyDoc_STRVAR(kqueue_queue_fileno_doc,
2090"fileno() -> int\n\
2091\n\
2092Return the kqueue control file descriptor.");
2093
2094static PyObject*
2095kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2100 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002103}
2104
2105PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2106"fromfd(fd) -> kqueue\n\
2107\n\
2108Create a kqueue object from a given control fd.");
2109
2110static PyObject *
2111kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 int nevents = 0;
2114 int gotevents = 0;
2115 int nchanges = 0;
2116 int i = 0;
2117 PyObject *otimeout = NULL;
2118 PyObject *ch = NULL;
Serhiy Storchakade072102017-10-12 22:17:46 +03002119 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 PyObject *result = NULL;
2121 struct kevent *evl = NULL;
2122 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002123 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002125 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (self->kqfd < 0)
2128 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2131 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (nevents < 0) {
2134 PyErr_Format(PyExc_ValueError,
2135 "Length of eventlist must be 0 or positive, got %d",
2136 nevents);
2137 return NULL;
2138 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 if (otimeout == Py_None || otimeout == NULL) {
2141 ptimeoutspec = NULL;
2142 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002143 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002144 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002145 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002146 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002147 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002148 "or None, got %.200s",
2149 Py_TYPE(otimeout)->tp_name);
2150 return NULL;
2151 }
2152
Victor Stinner4448c082015-03-31 11:48:34 +02002153 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002154 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002155
Victor Stinner4448c082015-03-31 11:48:34 +02002156 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 PyErr_SetString(PyExc_ValueError,
2158 "timeout must be positive or None");
2159 return NULL;
2160 }
Victor Stinner4448c082015-03-31 11:48:34 +02002161 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 if (ch != NULL && ch != Py_None) {
Serhiy Storchakade072102017-10-12 22:17:46 +03002165 seq = PySequence_Fast(ch, "changelist is not iterable");
2166 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 return NULL;
2168 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002169 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2170 PyErr_SetString(PyExc_OverflowError,
2171 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 goto error;
2173 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002174 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 chl = PyMem_New(struct kevent, nchanges);
2177 if (chl == NULL) {
2178 PyErr_NoMemory();
2179 goto error;
2180 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002181 for (i = 0; i < nchanges; ++i) {
2182 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 PyErr_SetString(PyExc_TypeError,
2185 "changelist must be an iterable of "
2186 "select.kevent objects");
2187 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002189 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002191 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 /* event list */
2195 if (nevents) {
2196 evl = PyMem_New(struct kevent, nevents);
2197 if (evl == NULL) {
2198 PyErr_NoMemory();
2199 goto error;
2200 }
2201 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002202
Victor Stinner4448c082015-03-31 11:48:34 +02002203 if (ptimeoutspec)
2204 deadline = _PyTime_GetMonotonicClock() + timeout;
2205
2206 do {
2207 Py_BEGIN_ALLOW_THREADS
2208 errno = 0;
2209 gotevents = kevent(self->kqfd, chl, nchanges,
2210 evl, nevents, ptimeoutspec);
2211 Py_END_ALLOW_THREADS
2212
2213 if (errno != EINTR)
2214 break;
2215
2216 /* kevent() was interrupted by a signal */
2217 if (PyErr_CheckSignals())
2218 goto error;
2219
2220 if (ptimeoutspec) {
2221 timeout = deadline - _PyTime_GetMonotonicClock();
2222 if (timeout < 0) {
2223 gotevents = 0;
2224 break;
2225 }
2226 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2227 goto error;
2228 /* retry kevent() with the recomputed timeout */
2229 }
2230 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 if (gotevents == -1) {
2233 PyErr_SetFromErrno(PyExc_OSError);
2234 goto error;
2235 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 result = PyList_New(gotevents);
2238 if (result == NULL) {
2239 goto error;
2240 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 for (i = 0; i < gotevents; i++) {
2243 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2246 if (ch == NULL) {
2247 goto error;
2248 }
2249 ch->e = evl[i];
2250 PyList_SET_ITEM(result, i, (PyObject *)ch);
2251 }
2252 PyMem_Free(chl);
2253 PyMem_Free(evl);
2254 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255
2256 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 PyMem_Free(chl);
2258 PyMem_Free(evl);
2259 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002260 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002262}
2263
2264PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002265"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002266\n\
2267Calls the kernel kevent function.\n\
Serhiy Storchakade072102017-10-12 22:17:46 +03002268- changelist must be an iterable of kevent objects describing the changes\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002269 to be made to the kernel's watch list or None.\n\
2270- max_events lets you specify the maximum number of events that the\n\
2271 kernel will return.\n\
2272- timeout is the maximum time to wait in seconds, or else None,\n\
2273 to wait forever. timeout accepts floats for smaller timeouts, too.");
2274
2275
2276static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2278 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2279 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2280 kqueue_queue_close_doc},
2281 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2282 kqueue_queue_fileno_doc},
2283 {"control", (PyCFunction)kqueue_queue_control,
2284 METH_VARARGS , kqueue_queue_control_doc},
2285 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002286};
2287
2288static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 {"closed", (getter)kqueue_queue_get_closed, NULL,
2290 "True if the kqueue handler is closed"},
2291 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002292};
2293
2294PyDoc_STRVAR(kqueue_queue_doc,
2295"Kqueue syscall wrapper.\n\
2296\n\
2297For example, to start watching a socket for input:\n\
2298>>> kq = kqueue()\n\
2299>>> sock = socket()\n\
2300>>> sock.connect((host, port))\n\
2301>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2302\n\
2303To wait one second for it to become writeable:\n\
2304>>> kq.control(None, 1, 1000)\n\
2305\n\
2306To stop listening:\n\
2307>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2308
2309static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 PyVarObject_HEAD_INIT(NULL, 0)
2311 "select.kqueue", /* tp_name */
2312 sizeof(kqueue_queue_Object), /* tp_basicsize */
2313 0, /* tp_itemsize */
2314 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2315 0, /* tp_print */
2316 0, /* tp_getattr */
2317 0, /* tp_setattr */
2318 0, /* tp_reserved */
2319 0, /* tp_repr */
2320 0, /* tp_as_number */
2321 0, /* tp_as_sequence */
2322 0, /* tp_as_mapping */
2323 0, /* tp_hash */
2324 0, /* tp_call */
2325 0, /* tp_str */
2326 0, /* tp_getattro */
2327 0, /* tp_setattro */
2328 0, /* tp_as_buffer */
2329 Py_TPFLAGS_DEFAULT, /* tp_flags */
2330 kqueue_queue_doc, /* tp_doc */
2331 0, /* tp_traverse */
2332 0, /* tp_clear */
2333 0, /* tp_richcompare */
2334 0, /* tp_weaklistoffset */
2335 0, /* tp_iter */
2336 0, /* tp_iternext */
2337 kqueue_queue_methods, /* tp_methods */
2338 0, /* tp_members */
2339 kqueue_queue_getsetlist, /* tp_getset */
2340 0, /* tp_base */
2341 0, /* tp_dict */
2342 0, /* tp_descr_get */
2343 0, /* tp_descr_set */
2344 0, /* tp_dictoffset */
2345 0, /* tp_init */
2346 0, /* tp_alloc */
2347 kqueue_queue_new, /* tp_new */
2348 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002349};
2350
2351#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002352
2353
2354
2355
2356
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002357/* ************************************************************************ */
2358
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002359PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002360"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2361\n\
2362Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002363The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002364rlist -- wait until ready for reading\n\
2365wlist -- wait until ready for writing\n\
2366xlist -- wait for an ``exceptional condition''\n\
2367If only one kind of condition is required, pass [] for the other lists.\n\
2368A file descriptor is either a socket or file object, or a small integer\n\
2369gotten from a fileno() method call on one of those.\n\
2370\n\
2371The optional 4th argument specifies a timeout in seconds; it may be\n\
2372a floating point number to specify fractions of seconds. If it is absent\n\
2373or None, the call will never time out.\n\
2374\n\
2375The return value is a tuple of three lists corresponding to the first three\n\
2376arguments; each contains the subset of the corresponding file descriptors\n\
2377that are ready.\n\
2378\n\
2379*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002380On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002381descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002382
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002383static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002385#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002387#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002388#ifdef HAVE_SYS_DEVPOLL_H
2389 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2390#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002392};
2393
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002394PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002395"This module supports asynchronous I/O on multiple file descriptors.\n\
2396\n\
2397*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002398On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002399
Martin v. Löwis1a214512008-06-11 05:26:20 +00002400
2401static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 PyModuleDef_HEAD_INIT,
2403 "select",
2404 module_doc,
2405 -1,
2406 select_methods,
2407 NULL,
2408 NULL,
2409 NULL,
2410 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002411};
2412
Jesus Cead8b9ae62011-11-14 19:07:41 +01002413
2414
2415
Mark Hammond62b1ab12002-07-23 06:31:15 +00002416PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002417PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 PyObject *m;
2420 m = PyModule_Create(&selectmodule);
2421 if (m == NULL)
2422 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002423
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002424 Py_INCREF(PyExc_OSError);
2425 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002426
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002427#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002428#ifdef HAVE_BROKEN_PIPE_BUF
2429#undef PIPE_BUF
2430#define PIPE_BUF 512
2431#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002432 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002433#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002434
Charles-François Natali986a56c2013-01-19 12:19:10 +01002435#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002436#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 if (select_have_broken_poll()) {
2438 if (PyObject_DelAttrString(m, "poll") == -1) {
2439 PyErr_Clear();
2440 }
2441 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002442#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002444#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 if (PyType_Ready(&poll_Type) < 0)
2446 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002447 PyModule_AddIntMacro(m, POLLIN);
2448 PyModule_AddIntMacro(m, POLLPRI);
2449 PyModule_AddIntMacro(m, POLLOUT);
2450 PyModule_AddIntMacro(m, POLLERR);
2451 PyModule_AddIntMacro(m, POLLHUP);
2452 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002453
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002454#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002455 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002456#endif
2457#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002458 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002459#endif
2460#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002461 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002462#endif
2463#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002464 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002465#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002466#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002467 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002468#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002469#ifdef POLLRDHUP
2470 /* Kernel 2.6.17+ */
2471 PyModule_AddIntMacro(m, POLLRDHUP);
2472#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002474#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002475
Jesus Cead8b9ae62011-11-14 19:07:41 +01002476#ifdef HAVE_SYS_DEVPOLL_H
2477 if (PyType_Ready(&devpoll_Type) < 0)
2478 return NULL;
2479#endif
2480
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002481#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2483 if (PyType_Ready(&pyEpoll_Type) < 0)
2484 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002486 Py_INCREF(&pyEpoll_Type);
2487 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002488
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002489 PyModule_AddIntMacro(m, EPOLLIN);
2490 PyModule_AddIntMacro(m, EPOLLOUT);
2491 PyModule_AddIntMacro(m, EPOLLPRI);
2492 PyModule_AddIntMacro(m, EPOLLERR);
2493 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002494#ifdef EPOLLRDHUP
2495 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002496 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002497#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002498 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002499#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002501 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002502#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002503#ifdef EPOLLEXCLUSIVE
2504 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2505#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002506
2507#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002508 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002509#endif
2510#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002511 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002512#endif
2513#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002514 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002515#endif
2516#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002517 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002518#endif
2519#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002520 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002521#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002522
Benjamin Peterson95c16622011-12-27 15:36:32 -06002523#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002524 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002525#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002526#endif /* HAVE_EPOLL */
2527
2528#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 kqueue_event_Type.tp_new = PyType_GenericNew;
2530 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2531 if(PyType_Ready(&kqueue_event_Type) < 0)
2532 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 Py_INCREF(&kqueue_event_Type);
2535 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002537 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2538 if(PyType_Ready(&kqueue_queue_Type) < 0)
2539 return NULL;
2540 Py_INCREF(&kqueue_queue_Type);
2541 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2542
2543 /* event filters */
2544 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2545 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002546#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002548#endif
2549#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002551#endif
2552#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002553 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002554#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002555#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002557#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002558#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002559 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002560#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 /* event flags */
2564 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2565 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2566 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2567 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2568 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2569 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002570
Berker Peksag7ec64562016-09-14 18:16:59 +03002571#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
2574#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2579 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002582#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002584#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2589 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2590 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2591 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2592 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2593 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2594 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002595#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2600 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2601 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2602 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2606 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2607 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002608#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609
2610 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002611#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2613 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2614 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002615#endif
2616
2617#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002619}