blob: d6b8fc1353bc7477d9fcf8d11cba2ac2889a62fc [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) {
282 n = 0;
283 break;
284 }
285 _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200286 /* retry select() with the recomputed timeout */
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200287 }
288 } while (1);
Guido van Rossumed233a51992-06-23 09:07:03 +0000289
Thomas Heller106f4c72002-09-24 16:51:00 +0000290#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200292 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000294#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200296 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000298#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 else {
300 /* any of these three calls can raise an exception. it's more
301 convenient to test for this after all three calls... but
302 is that acceptable?
303 */
304 ifdlist = set2list(&ifdset, rfd2obj);
305 ofdlist = set2list(&ofdset, wfd2obj);
306 efdlist = set2list(&efdset, efd2obj);
307 if (PyErr_Occurred())
308 ret = NULL;
309 else
310 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000311
Victor Stinnerbbf8ce52013-07-09 00:49:03 +0200312 Py_XDECREF(ifdlist);
313 Py_XDECREF(ofdlist);
314 Py_XDECREF(efdlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 }
316
Barry Warsawc1cb3601996-12-12 22:16:21 +0000317 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 reap_obj(rfd2obj);
319 reap_obj(wfd2obj);
320 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000321#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 PyMem_DEL(rfd2obj);
323 PyMem_DEL(wfd2obj);
324 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000325#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000327}
328
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000329#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000331 * poll() support
332 */
333
334typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 PyObject_HEAD
336 PyObject *dict;
337 int ufd_uptodate;
338 int ufd_len;
339 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300340 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000341} pollObject;
342
Jeremy Hylton938ace62002-07-17 16:30:39 +0000343static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346 contained within a pollObject. Return 1 on success, 0 on an error.
347*/
348
349static int
350update_ufd_array(pollObject *self)
351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 Py_ssize_t i, pos;
353 PyObject *key, *value;
354 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000355
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200356 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
358 if (self->ufds == NULL) {
359 self->ufds = old_ufds;
360 PyErr_NoMemory();
361 return 0;
362 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 i = pos = 0;
365 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200366 assert(i < self->ufd_len);
367 /* Never overflow */
368 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200369 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 i++;
371 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200372 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 self->ufd_uptodate = 1;
374 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000375}
376
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200377static int
378ushort_converter(PyObject *obj, void *ptr)
379{
380 unsigned long uval;
381
382 uval = PyLong_AsUnsignedLong(obj);
383 if (uval == (unsigned long)-1 && PyErr_Occurred())
384 return 0;
385 if (uval > USHRT_MAX) {
386 PyErr_SetString(PyExc_OverflowError,
387 "Python int too large for C unsigned short");
388 return 0;
389 }
390
391 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
392 return 1;
393}
394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000395PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000396"register(fd [, eventmask] ) -> None\n\n\
397Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000398fd -- either an integer, or an object with a fileno() method returning an\n\
399 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000400events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401
402static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200406 int fd;
407 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200410 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 fd = PyObject_AsFileDescriptor(o);
414 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 /* Add entry to the internal dictionary: the key is the
417 file descriptor, and the value is the event mask. */
418 key = PyLong_FromLong(fd);
419 if (key == NULL)
420 return NULL;
421 value = PyLong_FromLong(events);
422 if (value == NULL) {
423 Py_DECREF(key);
424 return NULL;
425 }
426 err = PyDict_SetItem(self->dict, key, value);
427 Py_DECREF(key);
428 Py_DECREF(value);
429 if (err < 0)
430 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 self->ufd_uptodate = 0;
433
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200434 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000437PyDoc_STRVAR(poll_modify_doc,
438"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000439Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000440fd -- either an integer, or an object with a fileno() method returning an\n\
441 int.\n\
442events -- an optional bitmask describing the type of events to check for");
443
444static PyObject *
445poll_modify(pollObject *self, PyObject *args)
446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200448 int fd;
449 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000451
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200452 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 fd = PyObject_AsFileDescriptor(o);
456 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 /* Modify registered fd */
459 key = PyLong_FromLong(fd);
460 if (key == NULL)
461 return NULL;
462 if (PyDict_GetItem(self->dict, key) == NULL) {
463 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200464 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200465 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return NULL;
467 }
468 value = PyLong_FromLong(events);
469 if (value == NULL) {
470 Py_DECREF(key);
471 return NULL;
472 }
473 err = PyDict_SetItem(self->dict, key, value);
474 Py_DECREF(key);
475 Py_DECREF(value);
476 if (err < 0)
477 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 self->ufd_uptodate = 0;
480
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200481 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000482}
483
484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000487Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
489static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 PyObject *key;
493 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 fd = PyObject_AsFileDescriptor( o );
496 if (fd == -1)
497 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 /* Check whether the fd is already in the array */
500 key = PyLong_FromLong(fd);
501 if (key == NULL)
502 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (PyDict_DelItem(self->dict, key) == -1) {
505 Py_DECREF(key);
506 /* This will simply raise the KeyError set by PyDict_DelItem
507 if the file descriptor isn't registered. */
508 return NULL;
509 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 Py_DECREF(key);
512 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000513
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200514 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515}
516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000517PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
519Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
522static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000524{
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200525 PyObject *result_list = NULL, *timeout_obj = NULL;
526 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PyObject *value = NULL, *num = NULL;
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200528 _PyTime_t timeout = -1, ms = -1, deadline = 0;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200529 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000530
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200531 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 return NULL;
533 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000534
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200535 if (timeout_obj != NULL && timeout_obj != Py_None) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200536 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100537 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200538 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
539 PyErr_SetString(PyExc_TypeError,
540 "timeout must be an integer or None");
541 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200543 }
544
Pablo Galindo2c15b292017-10-17 15:14:41 +0100545 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200546 if (ms < INT_MIN || ms > INT_MAX) {
547 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200549 }
550
Riccardo Coccioli6cfa9272017-10-17 21:45:07 +0200551 if (timeout >= 0) {
552 deadline = _PyTime_GetMonotonicClock() + timeout;
553 }
554 }
555
556 /* On some OSes, typically BSD-based ones, the timeout parameter of the
557 poll() syscall, when negative, must be exactly INFTIM, where defined,
558 or -1. See issue 31334. */
559 if (ms < 0) {
560#ifdef INFTIM
561 ms = INFTIM;
562#else
563 ms = -1;
564#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000566
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300567 /* Avoid concurrent poll() invocation, issue 8865 */
568 if (self->poll_running) {
569 PyErr_SetString(PyExc_RuntimeError,
570 "concurrent poll() invocation");
571 return NULL;
572 }
573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 /* Ensure the ufd array is up to date */
575 if (!self->ufd_uptodate)
576 if (update_ufd_array(self) == 0)
577 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000578
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300579 self->poll_running = 1;
580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200582 async_err = 0;
583 do {
584 Py_BEGIN_ALLOW_THREADS
585 errno = 0;
586 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
587 Py_END_ALLOW_THREADS
588
589 if (errno != EINTR)
590 break;
591
592 /* poll() was interrupted by a signal */
593 if (PyErr_CheckSignals()) {
594 async_err = 1;
595 break;
596 }
597
598 if (timeout >= 0) {
599 timeout = deadline - _PyTime_GetMonotonicClock();
600 if (timeout < 0) {
601 poll_result = 0;
602 break;
603 }
604 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
605 /* retry poll() with the recomputed timeout */
606 }
607 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000608
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300609 self->poll_running = 0;
610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200612 if (!async_err)
613 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 return NULL;
615 }
616
617 /* build the result list */
618
619 result_list = PyList_New(poll_result);
620 if (!result_list)
621 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200623 for (i = 0, j = 0; j < poll_result; j++) {
624 /* skip to the next fired descriptor */
625 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 i++;
627 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200628 /* if we hit a NULL return, set value to NULL
629 and break out of loop; code at end will
630 clean up result_list */
631 value = PyTuple_New(2);
632 if (value == NULL)
633 goto error;
634 num = PyLong_FromLong(self->ufds[i].fd);
635 if (num == NULL) {
636 Py_DECREF(value);
637 goto error;
638 }
639 PyTuple_SET_ITEM(value, 0, num);
640
641 /* The &0xffff is a workaround for AIX. 'revents'
642 is a 16-bit short, and IBM assigned POLLNVAL
643 to be 0x8000, so the conversion to int results
644 in a negative number. See SF bug #923315. */
645 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
646 if (num == NULL) {
647 Py_DECREF(value);
648 goto error;
649 }
650 PyTuple_SET_ITEM(value, 1, num);
651 if ((PyList_SetItem(result_list, j, value)) == -1) {
652 Py_DECREF(value);
653 goto error;
654 }
655 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 }
657 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658
659 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 Py_DECREF(result_list);
661 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000662}
663
664static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 {"register", (PyCFunction)poll_register,
666 METH_VARARGS, poll_register_doc},
667 {"modify", (PyCFunction)poll_modify,
668 METH_VARARGS, poll_modify_doc},
669 {"unregister", (PyCFunction)poll_unregister,
670 METH_O, poll_unregister_doc},
671 {"poll", (PyCFunction)poll_poll,
672 METH_VARARGS, poll_poll_doc},
673 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000674};
675
676static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000677newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 pollObject *self;
680 self = PyObject_New(pollObject, &poll_Type);
681 if (self == NULL)
682 return NULL;
683 /* ufd_uptodate is a Boolean, denoting whether the
684 array pointed to by ufds matches the contents of the dictionary. */
685 self->ufd_uptodate = 0;
686 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300687 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 self->dict = PyDict_New();
689 if (self->dict == NULL) {
690 Py_DECREF(self);
691 return NULL;
692 }
693 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000694}
695
696static void
697poll_dealloc(pollObject *self)
698{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 if (self->ufds != NULL)
700 PyMem_DEL(self->ufds);
701 Py_XDECREF(self->dict);
702 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000703}
704
Tim Peters0c322792002-07-17 16:49:03 +0000705static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 /* The ob_type field must be initialized in the module init function
707 * to be portable to Windows without using C++. */
708 PyVarObject_HEAD_INIT(NULL, 0)
709 "select.poll", /*tp_name*/
710 sizeof(pollObject), /*tp_basicsize*/
711 0, /*tp_itemsize*/
712 /* methods */
713 (destructor)poll_dealloc, /*tp_dealloc*/
714 0, /*tp_print*/
715 0, /*tp_getattr*/
716 0, /*tp_setattr*/
717 0, /*tp_reserved*/
718 0, /*tp_repr*/
719 0, /*tp_as_number*/
720 0, /*tp_as_sequence*/
721 0, /*tp_as_mapping*/
722 0, /*tp_hash*/
723 0, /*tp_call*/
724 0, /*tp_str*/
725 0, /*tp_getattro*/
726 0, /*tp_setattro*/
727 0, /*tp_as_buffer*/
728 Py_TPFLAGS_DEFAULT, /*tp_flags*/
729 0, /*tp_doc*/
730 0, /*tp_traverse*/
731 0, /*tp_clear*/
732 0, /*tp_richcompare*/
733 0, /*tp_weaklistoffset*/
734 0, /*tp_iter*/
735 0, /*tp_iternext*/
736 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000737};
738
Jesus Cead8b9ae62011-11-14 19:07:41 +0100739#ifdef HAVE_SYS_DEVPOLL_H
740typedef struct {
741 PyObject_HEAD
742 int fd_devpoll;
743 int max_n_fds;
744 int n_fds;
745 struct pollfd *fds;
746} devpollObject;
747
748static PyTypeObject devpoll_Type;
749
Victor Stinner13423c32013-08-22 00:19:50 +0200750static PyObject *
751devpoll_err_closed(void)
752{
753 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
754 return NULL;
755}
756
Jesus Cead8b9ae62011-11-14 19:07:41 +0100757static int devpoll_flush(devpollObject *self)
758{
759 int size, n;
760
761 if (!self->n_fds) return 0;
762
763 size = sizeof(struct pollfd)*self->n_fds;
764 self->n_fds = 0;
765
Victor Stinner54799672015-03-19 23:33:09 +0100766 n = _Py_write(self->fd_devpoll, self->fds, size);
767 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100768 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100769
Jesus Cead8b9ae62011-11-14 19:07:41 +0100770 if (n < size) {
771 /*
772 ** Data writed to /dev/poll is a binary data structure. It is not
773 ** clear what to do if a partial write occurred. For now, raise
774 ** an exception and see if we actually found this problem in
775 ** the wild.
776 ** See http://bugs.python.org/issue6397.
777 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300778 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100779 "Please, report at http://bugs.python.org/. "
780 "Data to report: Size tried: %d, actual size written: %d.",
781 size, n);
782 return -1;
783 }
784 return 0;
785}
786
787static PyObject *
788internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
789{
790 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200791 int fd;
792 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100793
Victor Stinner13423c32013-08-22 00:19:50 +0200794 if (self->fd_devpoll < 0)
795 return devpoll_err_closed();
796
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200797 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100798 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100799
800 fd = PyObject_AsFileDescriptor(o);
801 if (fd == -1) return NULL;
802
803 if (remove) {
804 self->fds[self->n_fds].fd = fd;
805 self->fds[self->n_fds].events = POLLREMOVE;
806
807 if (++self->n_fds == self->max_n_fds) {
808 if (devpoll_flush(self))
809 return NULL;
810 }
811 }
812
813 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200814 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100815
816 if (++self->n_fds == self->max_n_fds) {
817 if (devpoll_flush(self))
818 return NULL;
819 }
820
821 Py_RETURN_NONE;
822}
823
824PyDoc_STRVAR(devpoll_register_doc,
825"register(fd [, eventmask] ) -> None\n\n\
826Register a file descriptor with the polling object.\n\
827fd -- either an integer, or an object with a fileno() method returning an\n\
828 int.\n\
829events -- an optional bitmask describing the type of events to check for");
830
831static PyObject *
832devpoll_register(devpollObject *self, PyObject *args)
833{
834 return internal_devpoll_register(self, args, 0);
835}
836
837PyDoc_STRVAR(devpoll_modify_doc,
838"modify(fd[, eventmask]) -> None\n\n\
839Modify a possible already registered file descriptor.\n\
840fd -- either an integer, or an object with a fileno() method returning an\n\
841 int.\n\
842events -- an optional bitmask describing the type of events to check for");
843
844static PyObject *
845devpoll_modify(devpollObject *self, PyObject *args)
846{
847 return internal_devpoll_register(self, args, 1);
848}
849
850
851PyDoc_STRVAR(devpoll_unregister_doc,
852"unregister(fd) -> None\n\n\
853Remove a file descriptor being tracked by the polling object.");
854
855static PyObject *
856devpoll_unregister(devpollObject *self, PyObject *o)
857{
858 int fd;
859
Victor Stinner13423c32013-08-22 00:19:50 +0200860 if (self->fd_devpoll < 0)
861 return devpoll_err_closed();
862
Jesus Cead8b9ae62011-11-14 19:07:41 +0100863 fd = PyObject_AsFileDescriptor( o );
864 if (fd == -1)
865 return NULL;
866
867 self->fds[self->n_fds].fd = fd;
868 self->fds[self->n_fds].events = POLLREMOVE;
869
870 if (++self->n_fds == self->max_n_fds) {
871 if (devpoll_flush(self))
872 return NULL;
873 }
874
875 Py_RETURN_NONE;
876}
877
878PyDoc_STRVAR(devpoll_poll_doc,
879"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
880Polls the set of registered file descriptors, returning a list containing \n\
881any descriptors that have events or errors to report.");
882
883static PyObject *
884devpoll_poll(devpollObject *self, PyObject *args)
885{
886 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200887 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100888 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100889 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200890 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100891
Victor Stinner13423c32013-08-22 00:19:50 +0200892 if (self->fd_devpoll < 0)
893 return devpoll_err_closed();
894
Victor Stinner45ca48b2015-03-31 12:10:33 +0200895 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100896 return NULL;
897 }
898
899 /* Check values for timeout */
Victor Stinner45ca48b2015-03-31 12:10:33 +0200900 if (timeout_obj == NULL || timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100901 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200902 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100903 }
904 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200905 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +0100906 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200907 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
908 PyErr_SetString(PyExc_TypeError,
909 "timeout must be an integer or None");
910 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100911 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200912 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100913
Pablo Galindo2c15b292017-10-17 15:14:41 +0100914 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
Victor Stinner45ca48b2015-03-31 12:10:33 +0200915 if (ms < -1 || ms > INT_MAX) {
916 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
917 return NULL;
918 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100919 }
920
921 if (devpoll_flush(self))
922 return NULL;
923
924 dvp.dp_fds = self->fds;
925 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200926 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100927
Victor Stinner45ca48b2015-03-31 12:10:33 +0200928 if (timeout >= 0)
929 deadline = _PyTime_GetMonotonicClock() + timeout;
930
931 do {
932 /* call devpoll() */
933 Py_BEGIN_ALLOW_THREADS
934 errno = 0;
935 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
936 Py_END_ALLOW_THREADS
937
938 if (errno != EINTR)
939 break;
940
941 /* devpoll() was interrupted by a signal */
942 if (PyErr_CheckSignals())
943 return NULL;
944
945 if (timeout >= 0) {
946 timeout = deadline - _PyTime_GetMonotonicClock();
947 if (timeout < 0) {
948 poll_result = 0;
949 break;
950 }
951 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
952 dvp.dp_timeout = (int)ms;
953 /* retry devpoll() with the recomputed timeout */
954 }
955 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100956
957 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300958 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100959 return NULL;
960 }
961
962 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100963 result_list = PyList_New(poll_result);
964 if (!result_list)
965 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200966
967 for (i = 0; i < poll_result; i++) {
968 num1 = PyLong_FromLong(self->fds[i].fd);
969 num2 = PyLong_FromLong(self->fds[i].revents);
970 if ((num1 == NULL) || (num2 == NULL)) {
971 Py_XDECREF(num1);
972 Py_XDECREF(num2);
973 goto error;
974 }
975 value = PyTuple_Pack(2, num1, num2);
976 Py_DECREF(num1);
977 Py_DECREF(num2);
978 if (value == NULL)
979 goto error;
980 if ((PyList_SetItem(result_list, i, value)) == -1) {
981 Py_DECREF(value);
982 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100983 }
984 }
985
986 return result_list;
987
988 error:
989 Py_DECREF(result_list);
990 return NULL;
991}
992
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100993static int
994devpoll_internal_close(devpollObject *self)
995{
996 int save_errno = 0;
997 if (self->fd_devpoll >= 0) {
998 int fd = self->fd_devpoll;
999 self->fd_devpoll = -1;
1000 Py_BEGIN_ALLOW_THREADS
1001 if (close(fd) < 0)
1002 save_errno = errno;
1003 Py_END_ALLOW_THREADS
1004 }
1005 return save_errno;
1006}
1007
Victor Stinner13423c32013-08-22 00:19:50 +02001008static PyObject*
1009devpoll_close(devpollObject *self)
1010{
1011 errno = devpoll_internal_close(self);
1012 if (errno < 0) {
1013 PyErr_SetFromErrno(PyExc_OSError);
1014 return NULL;
1015 }
1016 Py_RETURN_NONE;
1017}
1018
1019PyDoc_STRVAR(devpoll_close_doc,
1020"close() -> None\n\
1021\n\
1022Close the devpoll file descriptor. Further operations on the devpoll\n\
1023object will raise an exception.");
1024
1025static PyObject*
1026devpoll_get_closed(devpollObject *self)
1027{
1028 if (self->fd_devpoll < 0)
1029 Py_RETURN_TRUE;
1030 else
1031 Py_RETURN_FALSE;
1032}
1033
1034static PyObject*
1035devpoll_fileno(devpollObject *self)
1036{
1037 if (self->fd_devpoll < 0)
1038 return devpoll_err_closed();
1039 return PyLong_FromLong(self->fd_devpoll);
1040}
1041
1042PyDoc_STRVAR(devpoll_fileno_doc,
1043"fileno() -> int\n\
1044\n\
1045Return the file descriptor.");
1046
Jesus Cead8b9ae62011-11-14 19:07:41 +01001047static PyMethodDef devpoll_methods[] = {
1048 {"register", (PyCFunction)devpoll_register,
1049 METH_VARARGS, devpoll_register_doc},
1050 {"modify", (PyCFunction)devpoll_modify,
1051 METH_VARARGS, devpoll_modify_doc},
1052 {"unregister", (PyCFunction)devpoll_unregister,
1053 METH_O, devpoll_unregister_doc},
1054 {"poll", (PyCFunction)devpoll_poll,
1055 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +02001056 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
1057 devpoll_close_doc},
1058 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
1059 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +01001060 {NULL, NULL} /* sentinel */
1061};
1062
Victor Stinner13423c32013-08-22 00:19:50 +02001063static PyGetSetDef devpoll_getsetlist[] = {
1064 {"closed", (getter)devpoll_get_closed, NULL,
1065 "True if the devpoll object is closed"},
1066 {0},
1067};
1068
Jesus Cead8b9ae62011-11-14 19:07:41 +01001069static devpollObject *
1070newDevPollObject(void)
1071{
1072 devpollObject *self;
1073 int fd_devpoll, limit_result;
1074 struct pollfd *fds;
1075 struct rlimit limit;
1076
Jesus Cead8b9ae62011-11-14 19:07:41 +01001077 /*
1078 ** If we try to process more that getrlimit()
1079 ** fds, the kernel will give an error, so
1080 ** we set the limit here. It is a dynamic
1081 ** value, because we can change rlimit() anytime.
1082 */
1083 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001084 if (limit_result == -1) {
1085 PyErr_SetFromErrno(PyExc_OSError);
1086 return NULL;
1087 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001088
1089 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1090 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001091 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001092
1093 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1094 if (fds == NULL) {
1095 close(fd_devpoll);
1096 PyErr_NoMemory();
1097 return NULL;
1098 }
1099
1100 self = PyObject_New(devpollObject, &devpoll_Type);
1101 if (self == NULL) {
1102 close(fd_devpoll);
1103 PyMem_DEL(fds);
1104 return NULL;
1105 }
1106 self->fd_devpoll = fd_devpoll;
1107 self->max_n_fds = limit.rlim_cur;
1108 self->n_fds = 0;
1109 self->fds = fds;
1110
1111 return self;
1112}
1113
1114static void
1115devpoll_dealloc(devpollObject *self)
1116{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001117 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001118 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001119 PyObject_Del(self);
1120}
1121
1122static PyTypeObject devpoll_Type = {
1123 /* The ob_type field must be initialized in the module init function
1124 * to be portable to Windows without using C++. */
1125 PyVarObject_HEAD_INIT(NULL, 0)
1126 "select.devpoll", /*tp_name*/
1127 sizeof(devpollObject), /*tp_basicsize*/
1128 0, /*tp_itemsize*/
1129 /* methods */
1130 (destructor)devpoll_dealloc, /*tp_dealloc*/
1131 0, /*tp_print*/
1132 0, /*tp_getattr*/
1133 0, /*tp_setattr*/
1134 0, /*tp_reserved*/
1135 0, /*tp_repr*/
1136 0, /*tp_as_number*/
1137 0, /*tp_as_sequence*/
1138 0, /*tp_as_mapping*/
1139 0, /*tp_hash*/
1140 0, /*tp_call*/
1141 0, /*tp_str*/
1142 0, /*tp_getattro*/
1143 0, /*tp_setattro*/
1144 0, /*tp_as_buffer*/
1145 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1146 0, /*tp_doc*/
1147 0, /*tp_traverse*/
1148 0, /*tp_clear*/
1149 0, /*tp_richcompare*/
1150 0, /*tp_weaklistoffset*/
1151 0, /*tp_iter*/
1152 0, /*tp_iternext*/
1153 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001154 0, /* tp_members */
1155 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001156};
1157#endif /* HAVE_SYS_DEVPOLL_H */
1158
1159
1160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001161PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001162"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001163unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001164
1165static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001166select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001169}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001170
Jesus Cead8b9ae62011-11-14 19:07:41 +01001171#ifdef HAVE_SYS_DEVPOLL_H
1172PyDoc_STRVAR(devpoll_doc,
1173"Returns a polling object, which supports registering and\n\
1174unregistering file descriptors, and then polling them for I/O events.");
1175
1176static PyObject *
1177select_devpoll(PyObject *self, PyObject *unused)
1178{
1179 return (PyObject *)newDevPollObject();
1180}
1181#endif
1182
1183
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001186 * On some systems poll() sets errno on invalid file descriptors. We test
1187 * for this at runtime because this bug may be fixed or introduced between
1188 * OS releases.
1189 */
1190static int select_have_broken_poll(void)
1191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 int poll_test;
1193 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 /* Create a file descriptor to make invalid */
1198 if (pipe(filedes) < 0) {
1199 return 1;
1200 }
1201 poll_struct.fd = filedes[0];
1202 close(filedes[0]);
1203 close(filedes[1]);
1204 poll_test = poll(&poll_struct, 1, 0);
1205 if (poll_test < 0) {
1206 return 1;
1207 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1208 return 1;
1209 }
1210 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211}
1212#endif /* __APPLE__ */
1213
1214#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001215
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001216#ifdef HAVE_EPOLL
1217/* **************************************************************************
1218 * epoll interface for Linux 2.6
1219 *
1220 * Written by Christian Heimes
1221 * Inspired by Twisted's _epoll.pyx and select.poll()
1222 */
1223
1224#ifdef HAVE_SYS_EPOLL_H
1225#include <sys/epoll.h>
1226#endif
1227
1228typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001230 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001231} pyEpoll_Object;
1232
1233static PyTypeObject pyEpoll_Type;
1234#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1235
1236static PyObject *
1237pyepoll_err_closed(void)
1238{
Victor Stinner13423c32013-08-22 00:19:50 +02001239 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001241}
1242
1243static int
1244pyepoll_internal_close(pyEpoll_Object *self)
1245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 int save_errno = 0;
1247 if (self->epfd >= 0) {
1248 int epfd = self->epfd;
1249 self->epfd = -1;
1250 Py_BEGIN_ALLOW_THREADS
1251 if (close(epfd) < 0)
1252 save_errno = errno;
1253 Py_END_ALLOW_THREADS
1254 }
1255 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256}
1257
1258static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001259newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 assert(type != NULL && type->tp_alloc != NULL);
1264 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1265 if (self == NULL)
1266 return NULL;
1267
1268 if (fd == -1) {
1269 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001270#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001271 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1272#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001273 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001274#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 Py_END_ALLOW_THREADS
1276 }
1277 else {
1278 self->epfd = fd;
1279 }
1280 if (self->epfd < 0) {
1281 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001282 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 return NULL;
1284 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001285
1286#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001287 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001288 Py_DECREF(self);
1289 return NULL;
1290 }
1291#endif
1292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001294}
1295
1296
1297static PyObject *
1298pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1299{
Miss Islington (bot)fd1c0922018-06-30 06:03:19 -07001300 int flags = 0, sizehint = -1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001301 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001302
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001303 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1304 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 return NULL;
Miss Islington (bot)fd1c0922018-06-30 06:03:19 -07001306 if (sizehint == -1) {
1307 sizehint = FD_SETSIZE - 1;
1308 }
1309 else if (sizehint <= 0) {
1310 PyErr_SetString(PyExc_ValueError, "sizehint must be positive or -1");
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001311 return NULL;
1312 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001313
1314#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001315 if (flags && flags != EPOLL_CLOEXEC) {
1316 PyErr_SetString(PyExc_OSError, "invalid flags");
1317 return NULL;
1318 }
Victor Stinnerb8d90322018-01-30 12:18:54 +01001319#endif
Berker Peksage2197d12016-09-26 23:30:41 +03001320 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001321}
1322
1323
1324static void
1325pyepoll_dealloc(pyEpoll_Object *self)
1326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 (void)pyepoll_internal_close(self);
1328 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001329}
1330
1331static PyObject*
1332pyepoll_close(pyEpoll_Object *self)
1333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 errno = pyepoll_internal_close(self);
1335 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001336 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 return NULL;
1338 }
1339 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001340}
1341
1342PyDoc_STRVAR(pyepoll_close_doc,
1343"close() -> None\n\
1344\n\
1345Close the epoll control file descriptor. Further operations on the epoll\n\
1346object will raise an exception.");
1347
1348static PyObject*
1349pyepoll_get_closed(pyEpoll_Object *self)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (self->epfd < 0)
1352 Py_RETURN_TRUE;
1353 else
1354 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001355}
1356
1357static PyObject*
1358pyepoll_fileno(pyEpoll_Object *self)
1359{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 if (self->epfd < 0)
1361 return pyepoll_err_closed();
1362 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363}
1364
1365PyDoc_STRVAR(pyepoll_fileno_doc,
1366"fileno() -> int\n\
1367\n\
1368Return the epoll control file descriptor.");
1369
1370static PyObject*
1371pyepoll_fromfd(PyObject *cls, PyObject *args)
1372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1376 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001377
Berker Peksage2197d12016-09-26 23:30:41 +03001378 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001379}
1380
1381PyDoc_STRVAR(pyepoll_fromfd_doc,
1382"fromfd(fd) -> epoll\n\
1383\n\
1384Create an epoll object from a given control fd.");
1385
1386static PyObject *
1387pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 struct epoll_event ev;
1390 int result;
1391 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 if (epfd < 0)
1394 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 fd = PyObject_AsFileDescriptor(pfd);
1397 if (fd == -1) {
1398 return NULL;
1399 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001400
Guido van Rossumee07b942013-12-06 17:46:22 -08001401 switch (op) {
1402 case EPOLL_CTL_ADD:
1403 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 ev.events = events;
1405 ev.data.fd = fd;
1406 Py_BEGIN_ALLOW_THREADS
1407 result = epoll_ctl(epfd, op, fd, &ev);
1408 Py_END_ALLOW_THREADS
1409 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001410 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1412 * operation required a non-NULL pointer in event, even
1413 * though this argument is ignored. */
1414 Py_BEGIN_ALLOW_THREADS
1415 result = epoll_ctl(epfd, op, fd, &ev);
1416 if (errno == EBADF) {
1417 /* fd already closed */
1418 result = 0;
1419 errno = 0;
1420 }
1421 Py_END_ALLOW_THREADS
1422 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001423 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 result = -1;
1425 errno = EINVAL;
1426 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001429 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 return NULL;
1431 }
1432 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001433}
1434
1435static PyObject *
1436pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 PyObject *pfd;
1439 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1440 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1443 &pfd, &events)) {
1444 return NULL;
1445 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001448}
1449
1450PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001451"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001452\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001453Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001454fd is the target file descriptor of the operation.\n\
1455events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001456is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001457\n\
1458The epoll interface supports all file descriptors that support poll.");
1459
1460static PyObject *
1461pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 PyObject *pfd;
1464 unsigned int events;
1465 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1468 &pfd, &events)) {
1469 return NULL;
1470 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001473}
1474
1475PyDoc_STRVAR(pyepoll_modify_doc,
1476"modify(fd, eventmask) -> None\n\
1477\n\
1478fd is the target file descriptor of the operation\n\
1479events is a bit set composed of the various EPOLL constants");
1480
1481static PyObject *
1482pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 PyObject *pfd;
1485 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1488 &pfd)) {
1489 return NULL;
1490 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001493}
1494
1495PyDoc_STRVAR(pyepoll_unregister_doc,
1496"unregister(fd) -> None\n\
1497\n\
1498fd is the target file descriptor of the operation.");
1499
1500static PyObject *
1501pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1502{
Victor Stinner41eba222015-03-30 21:59:21 +02001503 static char *kwlist[] = {"timeout", "maxevents", NULL};
1504 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 int maxevents = -1;
1506 int nfds, i;
1507 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001508 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001509 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 if (self->epfd < 0)
1512 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001513
Victor Stinner41eba222015-03-30 21:59:21 +02001514 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1515 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 return NULL;
1517 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001518
Victor Stinner41eba222015-03-30 21:59:21 +02001519 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001521 ms = -1;
1522 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 }
1524 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001525 /* epoll_wait() has a resolution of 1 millisecond, round towards
1526 infinity to wait at least timeout seconds. */
1527 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001528 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001529 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1530 PyErr_SetString(PyExc_TypeError,
1531 "timeout must be an integer or None");
1532 }
1533 return NULL;
1534 }
1535
1536 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1537 if (ms < INT_MIN || ms > INT_MAX) {
1538 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1539 return NULL;
1540 }
1541
1542 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001546 maxevents = FD_SETSIZE-1;
1547 }
1548 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 PyErr_Format(PyExc_ValueError,
1550 "maxevents must be greater than 0, got %d",
1551 maxevents);
1552 return NULL;
1553 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001554
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001555 evs = PyMem_New(struct epoll_event, maxevents);
1556 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001557 PyErr_NoMemory();
1558 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001560
Victor Stinner41eba222015-03-30 21:59:21 +02001561 do {
1562 Py_BEGIN_ALLOW_THREADS
1563 errno = 0;
1564 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1565 Py_END_ALLOW_THREADS
1566
1567 if (errno != EINTR)
1568 break;
1569
1570 /* poll() was interrupted by a signal */
1571 if (PyErr_CheckSignals())
1572 goto error;
1573
1574 if (timeout >= 0) {
1575 timeout = deadline - _PyTime_GetMonotonicClock();
1576 if (timeout < 0) {
1577 nfds = 0;
1578 break;
1579 }
1580 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1581 /* retry epoll_wait() with the recomputed timeout */
1582 }
1583 } while(1);
1584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001586 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 goto error;
1588 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 elist = PyList_New(nfds);
1591 if (elist == NULL) {
1592 goto error;
1593 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001596 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 if (etuple == NULL) {
1598 Py_CLEAR(elist);
1599 goto error;
1600 }
1601 PyList_SET_ITEM(elist, i, etuple);
1602 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001603
Christian Heimesf6cd9672008-03-26 13:45:42 +00001604 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001605 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001607}
1608
1609PyDoc_STRVAR(pyepoll_poll_doc,
1610"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1611\n\
1612Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1613in seconds (as float). -1 makes poll wait indefinitely.\n\
1614Up to maxevents are returned to the caller.");
1615
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001616static PyObject *
1617pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1618{
1619 if (self->epfd < 0)
1620 return pyepoll_err_closed();
1621
1622 Py_INCREF(self);
1623 return (PyObject *)self;
1624}
1625
1626static PyObject *
1627pyepoll_exit(PyObject *self, PyObject *args)
1628{
1629 _Py_IDENTIFIER(close);
1630
1631 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1632}
1633
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001634static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 {"fromfd", (PyCFunction)pyepoll_fromfd,
1636 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1637 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1638 pyepoll_close_doc},
1639 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1640 pyepoll_fileno_doc},
1641 {"modify", (PyCFunction)pyepoll_modify,
1642 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1643 {"register", (PyCFunction)pyepoll_register,
1644 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1645 {"unregister", (PyCFunction)pyepoll_unregister,
1646 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1647 {"poll", (PyCFunction)pyepoll_poll,
1648 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001649 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1650 NULL},
1651 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1652 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001654};
1655
1656static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 {"closed", (getter)pyepoll_get_closed, NULL,
1658 "True if the epoll handler is closed"},
1659 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001660};
1661
1662PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001663"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001664\n\
1665Returns an epolling object\n\
1666\n\
1667sizehint must be a positive integer or -1 for the default size. The\n\
1668sizehint is used to optimize internal data structures. It doesn't limit\n\
1669the maximum number of monitored events.");
1670
1671static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 PyVarObject_HEAD_INIT(NULL, 0)
1673 "select.epoll", /* tp_name */
1674 sizeof(pyEpoll_Object), /* tp_basicsize */
1675 0, /* tp_itemsize */
1676 (destructor)pyepoll_dealloc, /* tp_dealloc */
1677 0, /* tp_print */
1678 0, /* tp_getattr */
1679 0, /* tp_setattr */
1680 0, /* tp_reserved */
1681 0, /* tp_repr */
1682 0, /* tp_as_number */
1683 0, /* tp_as_sequence */
1684 0, /* tp_as_mapping */
1685 0, /* tp_hash */
1686 0, /* tp_call */
1687 0, /* tp_str */
1688 PyObject_GenericGetAttr, /* tp_getattro */
1689 0, /* tp_setattro */
1690 0, /* tp_as_buffer */
1691 Py_TPFLAGS_DEFAULT, /* tp_flags */
1692 pyepoll_doc, /* tp_doc */
1693 0, /* tp_traverse */
1694 0, /* tp_clear */
1695 0, /* tp_richcompare */
1696 0, /* tp_weaklistoffset */
1697 0, /* tp_iter */
1698 0, /* tp_iternext */
1699 pyepoll_methods, /* tp_methods */
1700 0, /* tp_members */
1701 pyepoll_getsetlist, /* tp_getset */
1702 0, /* tp_base */
1703 0, /* tp_dict */
1704 0, /* tp_descr_get */
1705 0, /* tp_descr_set */
1706 0, /* tp_dictoffset */
1707 0, /* tp_init */
1708 0, /* tp_alloc */
1709 pyepoll_new, /* tp_new */
1710 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001711};
1712
1713#endif /* HAVE_EPOLL */
1714
1715#ifdef HAVE_KQUEUE
1716/* **************************************************************************
1717 * kqueue interface for BSD
1718 *
1719 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1720 * All rights reserved.
1721 *
1722 * Redistribution and use in source and binary forms, with or without
1723 * modification, are permitted provided that the following conditions
1724 * are met:
1725 * 1. Redistributions of source code must retain the above copyright
1726 * notice, this list of conditions and the following disclaimer.
1727 * 2. Redistributions in binary form must reproduce the above copyright
1728 * notice, this list of conditions and the following disclaimer in the
1729 * documentation and/or other materials provided with the distribution.
1730 *
1731 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1732 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1733 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1734 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1735 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1736 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1737 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1738 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1739 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1740 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1741 * SUCH DAMAGE.
1742 */
1743
1744#ifdef HAVE_SYS_EVENT_H
1745#include <sys/event.h>
1746#endif
1747
1748PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001749"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001750\n\
1751This object is the equivalent of the struct kevent for the C API.\n\
1752\n\
1753See the kqueue manpage for more detailed information about the meaning\n\
1754of the arguments.\n\
1755\n\
1756One minor note: while you might hope that udata could store a\n\
1757reference to a python object, it cannot, because it is impossible to\n\
1758keep a proper reference count of the object once it's passed into the\n\
1759kernel. Therefore, I have restricted it to only storing an integer. I\n\
1760recommend ignoring it and simply using the 'ident' field to key off\n\
1761of. You could also set up a dictionary on the python side to store a\n\
1762udata->object mapping.");
1763
1764typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 PyObject_HEAD
1766 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001767} kqueue_event_Object;
1768
1769static PyTypeObject kqueue_event_Type;
1770
1771#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1772
1773typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 PyObject_HEAD
1775 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001776} kqueue_queue_Object;
1777
1778static PyTypeObject kqueue_queue_Type;
1779
1780#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1781
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001782#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1783# error uintptr_t does not match void *!
1784#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1785# define T_UINTPTRT T_ULONGLONG
1786# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001787# define UINTPTRT_FMT_UNIT "K"
1788# define INTPTRT_FMT_UNIT "L"
1789#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1790# define T_UINTPTRT T_ULONG
1791# define T_INTPTRT T_LONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001792# define UINTPTRT_FMT_UNIT "k"
1793# define INTPTRT_FMT_UNIT "l"
1794#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1795# define T_UINTPTRT T_UINT
1796# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001797# define UINTPTRT_FMT_UNIT "I"
1798# define INTPTRT_FMT_UNIT "i"
1799#else
1800# error uintptr_t does not match int, long, or long long!
1801#endif
1802
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001803#if SIZEOF_LONG_LONG == 8
1804# define T_INT64 T_LONGLONG
1805# define INT64_FMT_UNIT "L"
1806#elif SIZEOF_LONG == 8
1807# define T_INT64 T_LONG
1808# define INT64_FMT_UNIT "l"
1809#elif SIZEOF_INT == 8
1810# define T_INT64 T_INT
1811# define INT64_FMT_UNIT "i"
1812#else
1813# define INT64_FMT_UNIT "_"
1814#endif
1815
1816#if SIZEOF_LONG_LONG == 4
1817# define T_UINT32 T_ULONGLONG
1818# define UINT32_FMT_UNIT "K"
1819#elif SIZEOF_LONG == 4
1820# define T_UINT32 T_ULONG
1821# define UINT32_FMT_UNIT "k"
1822#elif SIZEOF_INT == 4
1823# define T_UINT32 T_UINT
1824# define UINT32_FMT_UNIT "I"
1825#else
1826# define UINT32_FMT_UNIT "_"
1827#endif
1828
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001829/*
1830 * kevent is not standard and its members vary across BSDs.
1831 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001832#ifdef __NetBSD__
1833# define FILTER_TYPE T_UINT32
1834# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1835# define FLAGS_TYPE T_UINT32
1836# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1837# define FFLAGS_TYPE T_UINT32
1838# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001839#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001840# define FILTER_TYPE T_SHORT
1841# define FILTER_FMT_UNIT "h"
1842# define FLAGS_TYPE T_USHORT
1843# define FLAGS_FMT_UNIT "H"
1844# define FFLAGS_TYPE T_UINT
1845# define FFLAGS_FMT_UNIT "I"
1846#endif
1847
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001848#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001849# define DATA_TYPE T_INT64
1850# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001851#else
1852# define DATA_TYPE T_INTPTRT
1853# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001854#endif
1855
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001856/* Unfortunately, we can't store python objects in udata, because
1857 * kevents in the kernel can be removed without warning, which would
1858 * forever lose the refcount on the object stored with it.
1859 */
1860
1861#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1862static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001863 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1864 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1865 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001867 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1869 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001870};
1871#undef KQ_OFF
1872
1873static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001874
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001875kqueue_event_repr(kqueue_event_Object *s)
1876{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 char buf[1024];
1878 PyOS_snprintf(
1879 buf, sizeof(buf),
1880 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001881 "data=0x%llx udata=%p>",
1882 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1883 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001885}
1886
1887static int
1888kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 PyObject *pfd;
1891 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1892 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001893 static const char fmt[] = "O|"
1894 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1895 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1900 &pfd, &(self->e.filter), &(self->e.flags),
1901 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1902 return -1;
1903 }
1904
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001905 if (PyLong_Check(pfd)) {
1906 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 }
1908 else {
1909 self->e.ident = PyObject_AsFileDescriptor(pfd);
1910 }
1911 if (PyErr_Occurred()) {
1912 return -1;
1913 }
1914 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001915}
1916
1917static PyObject *
1918kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001920{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001921 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001924 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001926
1927#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1928 result = CMP(s->e.ident, o->e.ident)
1929 : CMP(s->e.filter, o->e.filter)
1930 : CMP(s->e.flags, o->e.flags)
1931 : CMP(s->e.fflags, o->e.fflags)
1932 : CMP(s->e.data, o->e.data)
1933 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1934 : 0;
1935#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001936
stratakise8b19652017-11-02 11:32:54 +01001937 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001938}
1939
1940static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 PyVarObject_HEAD_INIT(NULL, 0)
1942 "select.kevent", /* tp_name */
1943 sizeof(kqueue_event_Object), /* tp_basicsize */
1944 0, /* tp_itemsize */
1945 0, /* tp_dealloc */
1946 0, /* tp_print */
1947 0, /* tp_getattr */
1948 0, /* tp_setattr */
1949 0, /* tp_reserved */
1950 (reprfunc)kqueue_event_repr, /* tp_repr */
1951 0, /* tp_as_number */
1952 0, /* tp_as_sequence */
1953 0, /* tp_as_mapping */
1954 0, /* tp_hash */
1955 0, /* tp_call */
1956 0, /* tp_str */
1957 0, /* tp_getattro */
1958 0, /* tp_setattro */
1959 0, /* tp_as_buffer */
1960 Py_TPFLAGS_DEFAULT, /* tp_flags */
1961 kqueue_event_doc, /* tp_doc */
1962 0, /* tp_traverse */
1963 0, /* tp_clear */
1964 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1965 0, /* tp_weaklistoffset */
1966 0, /* tp_iter */
1967 0, /* tp_iternext */
1968 0, /* tp_methods */
1969 kqueue_event_members, /* tp_members */
1970 0, /* tp_getset */
1971 0, /* tp_base */
1972 0, /* tp_dict */
1973 0, /* tp_descr_get */
1974 0, /* tp_descr_set */
1975 0, /* tp_dictoffset */
1976 (initproc)kqueue_event_init, /* tp_init */
1977 0, /* tp_alloc */
1978 0, /* tp_new */
1979 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001980};
1981
1982static PyObject *
1983kqueue_queue_err_closed(void)
1984{
Victor Stinner13423c32013-08-22 00:19:50 +02001985 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001987}
1988
1989static int
1990kqueue_queue_internal_close(kqueue_queue_Object *self)
1991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 int save_errno = 0;
1993 if (self->kqfd >= 0) {
1994 int kqfd = self->kqfd;
1995 self->kqfd = -1;
1996 Py_BEGIN_ALLOW_THREADS
1997 if (close(kqfd) < 0)
1998 save_errno = errno;
1999 Py_END_ALLOW_THREADS
2000 }
2001 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002002}
2003
2004static PyObject *
2005newKqueue_Object(PyTypeObject *type, SOCKET fd)
2006{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 kqueue_queue_Object *self;
2008 assert(type != NULL && type->tp_alloc != NULL);
2009 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
2010 if (self == NULL) {
2011 return NULL;
2012 }
2013
2014 if (fd == -1) {
2015 Py_BEGIN_ALLOW_THREADS
2016 self->kqfd = kqueue();
2017 Py_END_ALLOW_THREADS
2018 }
2019 else {
2020 self->kqfd = fd;
2021 }
2022 if (self->kqfd < 0) {
2023 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002024 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 return NULL;
2026 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002027
2028 if (fd == -1) {
2029 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2030 Py_DECREF(self);
2031 return NULL;
2032 }
2033 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002035}
2036
2037static PyObject *
2038kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2039{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002040 if (PyTuple_GET_SIZE(args) ||
2041 (kwds != NULL && PyDict_GET_SIZE(kwds))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 PyErr_SetString(PyExc_ValueError,
2043 "select.kqueue doesn't accept arguments");
2044 return NULL;
2045 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002048}
2049
2050static void
2051kqueue_queue_dealloc(kqueue_queue_Object *self)
2052{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 kqueue_queue_internal_close(self);
2054 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002055}
2056
2057static PyObject*
2058kqueue_queue_close(kqueue_queue_Object *self)
2059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 errno = kqueue_queue_internal_close(self);
2061 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002062 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 return NULL;
2064 }
2065 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002066}
2067
2068PyDoc_STRVAR(kqueue_queue_close_doc,
2069"close() -> None\n\
2070\n\
2071Close the kqueue control file descriptor. Further operations on the kqueue\n\
2072object will raise an exception.");
2073
2074static PyObject*
2075kqueue_queue_get_closed(kqueue_queue_Object *self)
2076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 if (self->kqfd < 0)
2078 Py_RETURN_TRUE;
2079 else
2080 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002081}
2082
2083static PyObject*
2084kqueue_queue_fileno(kqueue_queue_Object *self)
2085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 if (self->kqfd < 0)
2087 return kqueue_queue_err_closed();
2088 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002089}
2090
2091PyDoc_STRVAR(kqueue_queue_fileno_doc,
2092"fileno() -> int\n\
2093\n\
2094Return the kqueue control file descriptor.");
2095
2096static PyObject*
2097kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2102 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002105}
2106
2107PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2108"fromfd(fd) -> kqueue\n\
2109\n\
2110Create a kqueue object from a given control fd.");
2111
2112static PyObject *
2113kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 int nevents = 0;
2116 int gotevents = 0;
2117 int nchanges = 0;
2118 int i = 0;
2119 PyObject *otimeout = NULL;
2120 PyObject *ch = NULL;
Serhiy Storchakade072102017-10-12 22:17:46 +03002121 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 PyObject *result = NULL;
2123 struct kevent *evl = NULL;
2124 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002125 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002127 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 if (self->kqfd < 0)
2130 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2133 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 if (nevents < 0) {
2136 PyErr_Format(PyExc_ValueError,
2137 "Length of eventlist must be 0 or positive, got %d",
2138 nevents);
2139 return NULL;
2140 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 if (otimeout == Py_None || otimeout == NULL) {
2143 ptimeoutspec = NULL;
2144 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002145 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002146 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002147 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002148 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002149 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002150 "or None, got %.200s",
2151 Py_TYPE(otimeout)->tp_name);
2152 return NULL;
2153 }
2154
Victor Stinner4448c082015-03-31 11:48:34 +02002155 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002156 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002157
Victor Stinner4448c082015-03-31 11:48:34 +02002158 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 PyErr_SetString(PyExc_ValueError,
2160 "timeout must be positive or None");
2161 return NULL;
2162 }
Victor Stinner4448c082015-03-31 11:48:34 +02002163 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 if (ch != NULL && ch != Py_None) {
Serhiy Storchakade072102017-10-12 22:17:46 +03002167 seq = PySequence_Fast(ch, "changelist is not iterable");
2168 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 return NULL;
2170 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002171 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2172 PyErr_SetString(PyExc_OverflowError,
2173 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 goto error;
2175 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002176 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 chl = PyMem_New(struct kevent, nchanges);
2179 if (chl == NULL) {
2180 PyErr_NoMemory();
2181 goto error;
2182 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002183 for (i = 0; i < nchanges; ++i) {
2184 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 PyErr_SetString(PyExc_TypeError,
2187 "changelist must be an iterable of "
2188 "select.kevent objects");
2189 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002191 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002193 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 /* event list */
2197 if (nevents) {
2198 evl = PyMem_New(struct kevent, nevents);
2199 if (evl == NULL) {
2200 PyErr_NoMemory();
2201 goto error;
2202 }
2203 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002204
Victor Stinner4448c082015-03-31 11:48:34 +02002205 if (ptimeoutspec)
2206 deadline = _PyTime_GetMonotonicClock() + timeout;
2207
2208 do {
2209 Py_BEGIN_ALLOW_THREADS
2210 errno = 0;
2211 gotevents = kevent(self->kqfd, chl, nchanges,
2212 evl, nevents, ptimeoutspec);
2213 Py_END_ALLOW_THREADS
2214
2215 if (errno != EINTR)
2216 break;
2217
2218 /* kevent() was interrupted by a signal */
2219 if (PyErr_CheckSignals())
2220 goto error;
2221
2222 if (ptimeoutspec) {
2223 timeout = deadline - _PyTime_GetMonotonicClock();
2224 if (timeout < 0) {
2225 gotevents = 0;
2226 break;
2227 }
2228 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2229 goto error;
2230 /* retry kevent() with the recomputed timeout */
2231 }
2232 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 if (gotevents == -1) {
2235 PyErr_SetFromErrno(PyExc_OSError);
2236 goto error;
2237 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 result = PyList_New(gotevents);
2240 if (result == NULL) {
2241 goto error;
2242 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 for (i = 0; i < gotevents; i++) {
2245 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2248 if (ch == NULL) {
2249 goto error;
2250 }
2251 ch->e = evl[i];
2252 PyList_SET_ITEM(result, i, (PyObject *)ch);
2253 }
2254 PyMem_Free(chl);
2255 PyMem_Free(evl);
2256 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002257
2258 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 PyMem_Free(chl);
2260 PyMem_Free(evl);
2261 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002262 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002264}
2265
2266PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002267"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002268\n\
2269Calls the kernel kevent function.\n\
Serhiy Storchakade072102017-10-12 22:17:46 +03002270- changelist must be an iterable of kevent objects describing the changes\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002271 to be made to the kernel's watch list or None.\n\
2272- max_events lets you specify the maximum number of events that the\n\
2273 kernel will return.\n\
2274- timeout is the maximum time to wait in seconds, or else None,\n\
2275 to wait forever. timeout accepts floats for smaller timeouts, too.");
2276
2277
2278static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2280 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2281 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2282 kqueue_queue_close_doc},
2283 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2284 kqueue_queue_fileno_doc},
2285 {"control", (PyCFunction)kqueue_queue_control,
2286 METH_VARARGS , kqueue_queue_control_doc},
2287 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002288};
2289
2290static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 {"closed", (getter)kqueue_queue_get_closed, NULL,
2292 "True if the kqueue handler is closed"},
2293 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002294};
2295
2296PyDoc_STRVAR(kqueue_queue_doc,
2297"Kqueue syscall wrapper.\n\
2298\n\
2299For example, to start watching a socket for input:\n\
2300>>> kq = kqueue()\n\
2301>>> sock = socket()\n\
2302>>> sock.connect((host, port))\n\
2303>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2304\n\
2305To wait one second for it to become writeable:\n\
2306>>> kq.control(None, 1, 1000)\n\
2307\n\
2308To stop listening:\n\
2309>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2310
2311static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 PyVarObject_HEAD_INIT(NULL, 0)
2313 "select.kqueue", /* tp_name */
2314 sizeof(kqueue_queue_Object), /* tp_basicsize */
2315 0, /* tp_itemsize */
2316 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2317 0, /* tp_print */
2318 0, /* tp_getattr */
2319 0, /* tp_setattr */
2320 0, /* tp_reserved */
2321 0, /* tp_repr */
2322 0, /* tp_as_number */
2323 0, /* tp_as_sequence */
2324 0, /* tp_as_mapping */
2325 0, /* tp_hash */
2326 0, /* tp_call */
2327 0, /* tp_str */
2328 0, /* tp_getattro */
2329 0, /* tp_setattro */
2330 0, /* tp_as_buffer */
2331 Py_TPFLAGS_DEFAULT, /* tp_flags */
2332 kqueue_queue_doc, /* tp_doc */
2333 0, /* tp_traverse */
2334 0, /* tp_clear */
2335 0, /* tp_richcompare */
2336 0, /* tp_weaklistoffset */
2337 0, /* tp_iter */
2338 0, /* tp_iternext */
2339 kqueue_queue_methods, /* tp_methods */
2340 0, /* tp_members */
2341 kqueue_queue_getsetlist, /* tp_getset */
2342 0, /* tp_base */
2343 0, /* tp_dict */
2344 0, /* tp_descr_get */
2345 0, /* tp_descr_set */
2346 0, /* tp_dictoffset */
2347 0, /* tp_init */
2348 0, /* tp_alloc */
2349 kqueue_queue_new, /* tp_new */
2350 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002351};
2352
2353#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002354
2355
2356
2357
2358
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002359/* ************************************************************************ */
2360
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002361PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002362"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2363\n\
2364Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002365The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002366rlist -- wait until ready for reading\n\
2367wlist -- wait until ready for writing\n\
2368xlist -- wait for an ``exceptional condition''\n\
2369If only one kind of condition is required, pass [] for the other lists.\n\
2370A file descriptor is either a socket or file object, or a small integer\n\
2371gotten from a fileno() method call on one of those.\n\
2372\n\
2373The optional 4th argument specifies a timeout in seconds; it may be\n\
2374a floating point number to specify fractions of seconds. If it is absent\n\
2375or None, the call will never time out.\n\
2376\n\
2377The return value is a tuple of three lists corresponding to the first three\n\
2378arguments; each contains the subset of the corresponding file descriptors\n\
2379that are ready.\n\
2380\n\
2381*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002382On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002383descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002384
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002385static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002387#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002389#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002390#ifdef HAVE_SYS_DEVPOLL_H
2391 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2392#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002394};
2395
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002396PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002397"This module supports asynchronous I/O on multiple file descriptors.\n\
2398\n\
2399*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002400On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002401
Martin v. Löwis1a214512008-06-11 05:26:20 +00002402
2403static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 PyModuleDef_HEAD_INIT,
2405 "select",
2406 module_doc,
2407 -1,
2408 select_methods,
2409 NULL,
2410 NULL,
2411 NULL,
2412 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002413};
2414
Jesus Cead8b9ae62011-11-14 19:07:41 +01002415
2416
2417
Mark Hammond62b1ab12002-07-23 06:31:15 +00002418PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002419PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 PyObject *m;
2422 m = PyModule_Create(&selectmodule);
2423 if (m == NULL)
2424 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002425
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002426 Py_INCREF(PyExc_OSError);
2427 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002428
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002429#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002430#ifdef HAVE_BROKEN_PIPE_BUF
2431#undef PIPE_BUF
2432#define PIPE_BUF 512
2433#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002434 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002435#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002436
Charles-François Natali986a56c2013-01-19 12:19:10 +01002437#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002438#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 if (select_have_broken_poll()) {
2440 if (PyObject_DelAttrString(m, "poll") == -1) {
2441 PyErr_Clear();
2442 }
2443 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002444#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002446#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 if (PyType_Ready(&poll_Type) < 0)
2448 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002449 PyModule_AddIntMacro(m, POLLIN);
2450 PyModule_AddIntMacro(m, POLLPRI);
2451 PyModule_AddIntMacro(m, POLLOUT);
2452 PyModule_AddIntMacro(m, POLLERR);
2453 PyModule_AddIntMacro(m, POLLHUP);
2454 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002455
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002456#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002457 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002458#endif
2459#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002460 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002461#endif
2462#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002463 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002464#endif
2465#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002466 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002467#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002468#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002469 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002470#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002471#ifdef POLLRDHUP
2472 /* Kernel 2.6.17+ */
2473 PyModule_AddIntMacro(m, POLLRDHUP);
2474#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002476#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002477
Jesus Cead8b9ae62011-11-14 19:07:41 +01002478#ifdef HAVE_SYS_DEVPOLL_H
2479 if (PyType_Ready(&devpoll_Type) < 0)
2480 return NULL;
2481#endif
2482
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002483#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2485 if (PyType_Ready(&pyEpoll_Type) < 0)
2486 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 Py_INCREF(&pyEpoll_Type);
2489 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002490
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002491 PyModule_AddIntMacro(m, EPOLLIN);
2492 PyModule_AddIntMacro(m, EPOLLOUT);
2493 PyModule_AddIntMacro(m, EPOLLPRI);
2494 PyModule_AddIntMacro(m, EPOLLERR);
2495 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002496#ifdef EPOLLRDHUP
2497 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002498 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002499#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002500 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002501#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002503 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002504#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002505#ifdef EPOLLEXCLUSIVE
2506 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2507#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002508
2509#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002510 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002511#endif
2512#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002513 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002514#endif
2515#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002516 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002517#endif
2518#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002519 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002520#endif
2521#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002522 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002523#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002524
Benjamin Peterson95c16622011-12-27 15:36:32 -06002525#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002526 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002527#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002528#endif /* HAVE_EPOLL */
2529
2530#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 kqueue_event_Type.tp_new = PyType_GenericNew;
2532 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2533 if(PyType_Ready(&kqueue_event_Type) < 0)
2534 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 Py_INCREF(&kqueue_event_Type);
2537 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2540 if(PyType_Ready(&kqueue_queue_Type) < 0)
2541 return NULL;
2542 Py_INCREF(&kqueue_queue_Type);
2543 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2544
2545 /* event filters */
2546 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2547 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002548#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002549 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002550#endif
2551#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002552 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002553#endif
2554#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002556#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002557#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002559#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002560#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002562#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 /* event flags */
2566 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2567 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2568 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2569 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2570 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2571 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002572
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002575#endif
2576#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002578#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002580 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2581 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002584#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002586#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002589#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002590 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2591 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2592 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2593 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2594 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2595 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2596 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002597#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002600#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2602 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2604 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2605 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2608 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2609 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002610#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611
2612 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002613#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2615 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2616 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002617#endif
2618
2619#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002621}