blob: f2f5cc86cdbe5113a529ad99f895bce979fba27c [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{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001300 int flags = 0, sizehint = FD_SETSIZE - 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;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001306 if (sizehint < 0) {
1307 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1308 return NULL;
1309 }
Berker Peksage2197d12016-09-26 23:30:41 +03001310 if (flags && flags != EPOLL_CLOEXEC) {
1311 PyErr_SetString(PyExc_OSError, "invalid flags");
1312 return NULL;
1313 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001314
Berker Peksage2197d12016-09-26 23:30:41 +03001315 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001316}
1317
1318
1319static void
1320pyepoll_dealloc(pyEpoll_Object *self)
1321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 (void)pyepoll_internal_close(self);
1323 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001324}
1325
1326static PyObject*
1327pyepoll_close(pyEpoll_Object *self)
1328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 errno = pyepoll_internal_close(self);
1330 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001331 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 return NULL;
1333 }
1334 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001335}
1336
1337PyDoc_STRVAR(pyepoll_close_doc,
1338"close() -> None\n\
1339\n\
1340Close the epoll control file descriptor. Further operations on the epoll\n\
1341object will raise an exception.");
1342
1343static PyObject*
1344pyepoll_get_closed(pyEpoll_Object *self)
1345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 if (self->epfd < 0)
1347 Py_RETURN_TRUE;
1348 else
1349 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001350}
1351
1352static PyObject*
1353pyepoll_fileno(pyEpoll_Object *self)
1354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 if (self->epfd < 0)
1356 return pyepoll_err_closed();
1357 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001358}
1359
1360PyDoc_STRVAR(pyepoll_fileno_doc,
1361"fileno() -> int\n\
1362\n\
1363Return the epoll control file descriptor.");
1364
1365static PyObject*
1366pyepoll_fromfd(PyObject *cls, PyObject *args)
1367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1371 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001372
Berker Peksage2197d12016-09-26 23:30:41 +03001373 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001374}
1375
1376PyDoc_STRVAR(pyepoll_fromfd_doc,
1377"fromfd(fd) -> epoll\n\
1378\n\
1379Create an epoll object from a given control fd.");
1380
1381static PyObject *
1382pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 struct epoll_event ev;
1385 int result;
1386 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 if (epfd < 0)
1389 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 fd = PyObject_AsFileDescriptor(pfd);
1392 if (fd == -1) {
1393 return NULL;
1394 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001395
Guido van Rossumee07b942013-12-06 17:46:22 -08001396 switch (op) {
1397 case EPOLL_CTL_ADD:
1398 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 ev.events = events;
1400 ev.data.fd = fd;
1401 Py_BEGIN_ALLOW_THREADS
1402 result = epoll_ctl(epfd, op, fd, &ev);
1403 Py_END_ALLOW_THREADS
1404 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001405 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1407 * operation required a non-NULL pointer in event, even
1408 * though this argument is ignored. */
1409 Py_BEGIN_ALLOW_THREADS
1410 result = epoll_ctl(epfd, op, fd, &ev);
1411 if (errno == EBADF) {
1412 /* fd already closed */
1413 result = 0;
1414 errno = 0;
1415 }
1416 Py_END_ALLOW_THREADS
1417 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001418 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 result = -1;
1420 errno = EINVAL;
1421 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001424 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 return NULL;
1426 }
1427 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428}
1429
1430static PyObject *
1431pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 PyObject *pfd;
1434 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1435 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1438 &pfd, &events)) {
1439 return NULL;
1440 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001443}
1444
1445PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001446"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001447\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001448Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001449fd is the target file descriptor of the operation.\n\
1450events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001451is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001452\n\
1453The epoll interface supports all file descriptors that support poll.");
1454
1455static PyObject *
1456pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 PyObject *pfd;
1459 unsigned int events;
1460 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1463 &pfd, &events)) {
1464 return NULL;
1465 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001468}
1469
1470PyDoc_STRVAR(pyepoll_modify_doc,
1471"modify(fd, eventmask) -> None\n\
1472\n\
1473fd is the target file descriptor of the operation\n\
1474events is a bit set composed of the various EPOLL constants");
1475
1476static PyObject *
1477pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 PyObject *pfd;
1480 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1483 &pfd)) {
1484 return NULL;
1485 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001488}
1489
1490PyDoc_STRVAR(pyepoll_unregister_doc,
1491"unregister(fd) -> None\n\
1492\n\
1493fd is the target file descriptor of the operation.");
1494
1495static PyObject *
1496pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1497{
Victor Stinner41eba222015-03-30 21:59:21 +02001498 static char *kwlist[] = {"timeout", "maxevents", NULL};
1499 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 int maxevents = -1;
1501 int nfds, i;
1502 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001503 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001504 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 if (self->epfd < 0)
1507 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001508
Victor Stinner41eba222015-03-30 21:59:21 +02001509 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1510 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return NULL;
1512 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001513
Victor Stinner41eba222015-03-30 21:59:21 +02001514 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001516 ms = -1;
1517 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 }
1519 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001520 /* epoll_wait() has a resolution of 1 millisecond, round towards
1521 infinity to wait at least timeout seconds. */
1522 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
Pablo Galindo2c15b292017-10-17 15:14:41 +01001523 _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinner41eba222015-03-30 21:59:21 +02001524 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1525 PyErr_SetString(PyExc_TypeError,
1526 "timeout must be an integer or None");
1527 }
1528 return NULL;
1529 }
1530
1531 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1532 if (ms < INT_MIN || ms > INT_MAX) {
1533 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1534 return NULL;
1535 }
1536
1537 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001541 maxevents = FD_SETSIZE-1;
1542 }
1543 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 PyErr_Format(PyExc_ValueError,
1545 "maxevents must be greater than 0, got %d",
1546 maxevents);
1547 return NULL;
1548 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001549
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001550 evs = PyMem_New(struct epoll_event, maxevents);
1551 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001552 PyErr_NoMemory();
1553 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001555
Victor Stinner41eba222015-03-30 21:59:21 +02001556 do {
1557 Py_BEGIN_ALLOW_THREADS
1558 errno = 0;
1559 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1560 Py_END_ALLOW_THREADS
1561
1562 if (errno != EINTR)
1563 break;
1564
1565 /* poll() was interrupted by a signal */
1566 if (PyErr_CheckSignals())
1567 goto error;
1568
1569 if (timeout >= 0) {
1570 timeout = deadline - _PyTime_GetMonotonicClock();
1571 if (timeout < 0) {
1572 nfds = 0;
1573 break;
1574 }
1575 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1576 /* retry epoll_wait() with the recomputed timeout */
1577 }
1578 } while(1);
1579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001581 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 goto error;
1583 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 elist = PyList_New(nfds);
1586 if (elist == NULL) {
1587 goto error;
1588 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001591 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 if (etuple == NULL) {
1593 Py_CLEAR(elist);
1594 goto error;
1595 }
1596 PyList_SET_ITEM(elist, i, etuple);
1597 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001598
Christian Heimesf6cd9672008-03-26 13:45:42 +00001599 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001600 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001602}
1603
1604PyDoc_STRVAR(pyepoll_poll_doc,
1605"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1606\n\
1607Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1608in seconds (as float). -1 makes poll wait indefinitely.\n\
1609Up to maxevents are returned to the caller.");
1610
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001611static PyObject *
1612pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1613{
1614 if (self->epfd < 0)
1615 return pyepoll_err_closed();
1616
1617 Py_INCREF(self);
1618 return (PyObject *)self;
1619}
1620
1621static PyObject *
1622pyepoll_exit(PyObject *self, PyObject *args)
1623{
1624 _Py_IDENTIFIER(close);
1625
1626 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1627}
1628
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001629static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 {"fromfd", (PyCFunction)pyepoll_fromfd,
1631 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1632 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1633 pyepoll_close_doc},
1634 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1635 pyepoll_fileno_doc},
1636 {"modify", (PyCFunction)pyepoll_modify,
1637 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1638 {"register", (PyCFunction)pyepoll_register,
1639 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1640 {"unregister", (PyCFunction)pyepoll_unregister,
1641 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1642 {"poll", (PyCFunction)pyepoll_poll,
1643 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001644 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1645 NULL},
1646 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1647 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001649};
1650
1651static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 {"closed", (getter)pyepoll_get_closed, NULL,
1653 "True if the epoll handler is closed"},
1654 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001655};
1656
1657PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001658"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001659\n\
1660Returns an epolling object\n\
1661\n\
1662sizehint must be a positive integer or -1 for the default size. The\n\
1663sizehint is used to optimize internal data structures. It doesn't limit\n\
1664the maximum number of monitored events.");
1665
1666static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 PyVarObject_HEAD_INIT(NULL, 0)
1668 "select.epoll", /* tp_name */
1669 sizeof(pyEpoll_Object), /* tp_basicsize */
1670 0, /* tp_itemsize */
1671 (destructor)pyepoll_dealloc, /* tp_dealloc */
1672 0, /* tp_print */
1673 0, /* tp_getattr */
1674 0, /* tp_setattr */
1675 0, /* tp_reserved */
1676 0, /* tp_repr */
1677 0, /* tp_as_number */
1678 0, /* tp_as_sequence */
1679 0, /* tp_as_mapping */
1680 0, /* tp_hash */
1681 0, /* tp_call */
1682 0, /* tp_str */
1683 PyObject_GenericGetAttr, /* tp_getattro */
1684 0, /* tp_setattro */
1685 0, /* tp_as_buffer */
1686 Py_TPFLAGS_DEFAULT, /* tp_flags */
1687 pyepoll_doc, /* tp_doc */
1688 0, /* tp_traverse */
1689 0, /* tp_clear */
1690 0, /* tp_richcompare */
1691 0, /* tp_weaklistoffset */
1692 0, /* tp_iter */
1693 0, /* tp_iternext */
1694 pyepoll_methods, /* tp_methods */
1695 0, /* tp_members */
1696 pyepoll_getsetlist, /* tp_getset */
1697 0, /* tp_base */
1698 0, /* tp_dict */
1699 0, /* tp_descr_get */
1700 0, /* tp_descr_set */
1701 0, /* tp_dictoffset */
1702 0, /* tp_init */
1703 0, /* tp_alloc */
1704 pyepoll_new, /* tp_new */
1705 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001706};
1707
1708#endif /* HAVE_EPOLL */
1709
1710#ifdef HAVE_KQUEUE
1711/* **************************************************************************
1712 * kqueue interface for BSD
1713 *
1714 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1715 * All rights reserved.
1716 *
1717 * Redistribution and use in source and binary forms, with or without
1718 * modification, are permitted provided that the following conditions
1719 * are met:
1720 * 1. Redistributions of source code must retain the above copyright
1721 * notice, this list of conditions and the following disclaimer.
1722 * 2. Redistributions in binary form must reproduce the above copyright
1723 * notice, this list of conditions and the following disclaimer in the
1724 * documentation and/or other materials provided with the distribution.
1725 *
1726 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1727 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1728 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1729 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1730 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1731 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1732 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1733 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1734 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1735 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1736 * SUCH DAMAGE.
1737 */
1738
1739#ifdef HAVE_SYS_EVENT_H
1740#include <sys/event.h>
1741#endif
1742
1743PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001744"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001745\n\
1746This object is the equivalent of the struct kevent for the C API.\n\
1747\n\
1748See the kqueue manpage for more detailed information about the meaning\n\
1749of the arguments.\n\
1750\n\
1751One minor note: while you might hope that udata could store a\n\
1752reference to a python object, it cannot, because it is impossible to\n\
1753keep a proper reference count of the object once it's passed into the\n\
1754kernel. Therefore, I have restricted it to only storing an integer. I\n\
1755recommend ignoring it and simply using the 'ident' field to key off\n\
1756of. You could also set up a dictionary on the python side to store a\n\
1757udata->object mapping.");
1758
1759typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 PyObject_HEAD
1761 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001762} kqueue_event_Object;
1763
1764static PyTypeObject kqueue_event_Type;
1765
1766#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1767
1768typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 PyObject_HEAD
1770 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001771} kqueue_queue_Object;
1772
1773static PyTypeObject kqueue_queue_Type;
1774
1775#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1776
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001777#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1778# error uintptr_t does not match void *!
1779#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1780# define T_UINTPTRT T_ULONGLONG
1781# define T_INTPTRT T_LONGLONG
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001782# define UINTPTRT_FMT_UNIT "K"
1783# define INTPTRT_FMT_UNIT "L"
1784#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1785# define T_UINTPTRT T_ULONG
1786# define T_INTPTRT T_LONG
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_INT)
1790# define T_UINTPTRT T_UINT
1791# define T_INTPTRT T_INT
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001792# define UINTPTRT_FMT_UNIT "I"
1793# define INTPTRT_FMT_UNIT "i"
1794#else
1795# error uintptr_t does not match int, long, or long long!
1796#endif
1797
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001798#if SIZEOF_LONG_LONG == 8
1799# define T_INT64 T_LONGLONG
1800# define INT64_FMT_UNIT "L"
1801#elif SIZEOF_LONG == 8
1802# define T_INT64 T_LONG
1803# define INT64_FMT_UNIT "l"
1804#elif SIZEOF_INT == 8
1805# define T_INT64 T_INT
1806# define INT64_FMT_UNIT "i"
1807#else
1808# define INT64_FMT_UNIT "_"
1809#endif
1810
1811#if SIZEOF_LONG_LONG == 4
1812# define T_UINT32 T_ULONGLONG
1813# define UINT32_FMT_UNIT "K"
1814#elif SIZEOF_LONG == 4
1815# define T_UINT32 T_ULONG
1816# define UINT32_FMT_UNIT "k"
1817#elif SIZEOF_INT == 4
1818# define T_UINT32 T_UINT
1819# define UINT32_FMT_UNIT "I"
1820#else
1821# define UINT32_FMT_UNIT "_"
1822#endif
1823
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001824/*
1825 * kevent is not standard and its members vary across BSDs.
1826 */
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001827#ifdef __NetBSD__
1828# define FILTER_TYPE T_UINT32
1829# define FILTER_FMT_UNIT UINT32_FMT_UNIT
1830# define FLAGS_TYPE T_UINT32
1831# define FLAGS_FMT_UNIT UINT32_FMT_UNIT
1832# define FFLAGS_TYPE T_UINT32
1833# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001834#else
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001835# define FILTER_TYPE T_SHORT
1836# define FILTER_FMT_UNIT "h"
1837# define FLAGS_TYPE T_USHORT
1838# define FLAGS_FMT_UNIT "H"
1839# define FFLAGS_TYPE T_UINT
1840# define FFLAGS_FMT_UNIT "I"
1841#endif
1842
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001843#if defined(__NetBSD__) || defined(__OpenBSD__)
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001844# define DATA_TYPE T_INT64
1845# define DATA_FMT_UNIT INT64_FMT_UNIT
Serhiy Storchaka2298fad2017-10-31 18:18:21 +02001846#else
1847# define DATA_TYPE T_INTPTRT
1848# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001849#endif
1850
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001851/* Unfortunately, we can't store python objects in udata, because
1852 * kevents in the kernel can be removed without warning, which would
1853 * forever lose the refcount on the object stored with it.
1854 */
1855
1856#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1857static struct PyMemberDef kqueue_event_members[] = {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001858 {"ident", T_UINTPTRT, KQ_OFF(e.ident)},
1859 {"filter", FILTER_TYPE, KQ_OFF(e.filter)},
1860 {"flags", FLAGS_TYPE, KQ_OFF(e.flags)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001862 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1864 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001865};
1866#undef KQ_OFF
1867
1868static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001869
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001870kqueue_event_repr(kqueue_event_Object *s)
1871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 char buf[1024];
1873 PyOS_snprintf(
1874 buf, sizeof(buf),
1875 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001876 "data=0x%llx udata=%p>",
1877 (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
1878 (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880}
1881
1882static int
1883kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyObject *pfd;
1886 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1887 "data", "udata", NULL};
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001888 static const char fmt[] = "O|"
1889 FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
1890 UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1895 &pfd, &(self->e.filter), &(self->e.flags),
1896 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1897 return -1;
1898 }
1899
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001900 if (PyLong_Check(pfd)) {
1901 self->e.ident = PyLong_AsSize_t(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 }
1903 else {
1904 self->e.ident = PyObject_AsFileDescriptor(pfd);
1905 }
1906 if (PyErr_Occurred()) {
1907 return -1;
1908 }
1909 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001910}
1911
1912static PyObject *
1913kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001915{
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001916 int result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 if (!kqueue_event_Check(o)) {
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001919 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 }
Serhiy Storchakab9052a02017-10-31 13:59:55 +02001921
1922#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
1923 result = CMP(s->e.ident, o->e.ident)
1924 : CMP(s->e.filter, o->e.filter)
1925 : CMP(s->e.flags, o->e.flags)
1926 : CMP(s->e.fflags, o->e.fflags)
1927 : CMP(s->e.data, o->e.data)
1928 : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
1929 : 0;
1930#undef CMP
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001931
stratakise8b19652017-11-02 11:32:54 +01001932 Py_RETURN_RICHCOMPARE(result, 0, op);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001933}
1934
1935static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 PyVarObject_HEAD_INIT(NULL, 0)
1937 "select.kevent", /* tp_name */
1938 sizeof(kqueue_event_Object), /* tp_basicsize */
1939 0, /* tp_itemsize */
1940 0, /* tp_dealloc */
1941 0, /* tp_print */
1942 0, /* tp_getattr */
1943 0, /* tp_setattr */
1944 0, /* tp_reserved */
1945 (reprfunc)kqueue_event_repr, /* tp_repr */
1946 0, /* tp_as_number */
1947 0, /* tp_as_sequence */
1948 0, /* tp_as_mapping */
1949 0, /* tp_hash */
1950 0, /* tp_call */
1951 0, /* tp_str */
1952 0, /* tp_getattro */
1953 0, /* tp_setattro */
1954 0, /* tp_as_buffer */
1955 Py_TPFLAGS_DEFAULT, /* tp_flags */
1956 kqueue_event_doc, /* tp_doc */
1957 0, /* tp_traverse */
1958 0, /* tp_clear */
1959 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1960 0, /* tp_weaklistoffset */
1961 0, /* tp_iter */
1962 0, /* tp_iternext */
1963 0, /* tp_methods */
1964 kqueue_event_members, /* tp_members */
1965 0, /* tp_getset */
1966 0, /* tp_base */
1967 0, /* tp_dict */
1968 0, /* tp_descr_get */
1969 0, /* tp_descr_set */
1970 0, /* tp_dictoffset */
1971 (initproc)kqueue_event_init, /* tp_init */
1972 0, /* tp_alloc */
1973 0, /* tp_new */
1974 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001975};
1976
1977static PyObject *
1978kqueue_queue_err_closed(void)
1979{
Victor Stinner13423c32013-08-22 00:19:50 +02001980 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001982}
1983
1984static int
1985kqueue_queue_internal_close(kqueue_queue_Object *self)
1986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 int save_errno = 0;
1988 if (self->kqfd >= 0) {
1989 int kqfd = self->kqfd;
1990 self->kqfd = -1;
1991 Py_BEGIN_ALLOW_THREADS
1992 if (close(kqfd) < 0)
1993 save_errno = errno;
1994 Py_END_ALLOW_THREADS
1995 }
1996 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001997}
1998
1999static PyObject *
2000newKqueue_Object(PyTypeObject *type, SOCKET fd)
2001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 kqueue_queue_Object *self;
2003 assert(type != NULL && type->tp_alloc != NULL);
2004 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
2005 if (self == NULL) {
2006 return NULL;
2007 }
2008
2009 if (fd == -1) {
2010 Py_BEGIN_ALLOW_THREADS
2011 self->kqfd = kqueue();
2012 Py_END_ALLOW_THREADS
2013 }
2014 else {
2015 self->kqfd = fd;
2016 }
2017 if (self->kqfd < 0) {
2018 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002019 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 return NULL;
2021 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002022
2023 if (fd == -1) {
2024 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2025 Py_DECREF(self);
2026 return NULL;
2027 }
2028 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002030}
2031
2032static PyObject *
2033kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2034{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002035 if (PyTuple_GET_SIZE(args) ||
2036 (kwds != NULL && PyDict_GET_SIZE(kwds))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 PyErr_SetString(PyExc_ValueError,
2038 "select.kqueue doesn't accept arguments");
2039 return NULL;
2040 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002043}
2044
2045static void
2046kqueue_queue_dealloc(kqueue_queue_Object *self)
2047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 kqueue_queue_internal_close(self);
2049 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002050}
2051
2052static PyObject*
2053kqueue_queue_close(kqueue_queue_Object *self)
2054{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 errno = kqueue_queue_internal_close(self);
2056 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002057 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 return NULL;
2059 }
2060 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002061}
2062
2063PyDoc_STRVAR(kqueue_queue_close_doc,
2064"close() -> None\n\
2065\n\
2066Close the kqueue control file descriptor. Further operations on the kqueue\n\
2067object will raise an exception.");
2068
2069static PyObject*
2070kqueue_queue_get_closed(kqueue_queue_Object *self)
2071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 if (self->kqfd < 0)
2073 Py_RETURN_TRUE;
2074 else
2075 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076}
2077
2078static PyObject*
2079kqueue_queue_fileno(kqueue_queue_Object *self)
2080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 if (self->kqfd < 0)
2082 return kqueue_queue_err_closed();
2083 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002084}
2085
2086PyDoc_STRVAR(kqueue_queue_fileno_doc,
2087"fileno() -> int\n\
2088\n\
2089Return the kqueue control file descriptor.");
2090
2091static PyObject*
2092kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2097 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002100}
2101
2102PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2103"fromfd(fd) -> kqueue\n\
2104\n\
2105Create a kqueue object from a given control fd.");
2106
2107static PyObject *
2108kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 int nevents = 0;
2111 int gotevents = 0;
2112 int nchanges = 0;
2113 int i = 0;
2114 PyObject *otimeout = NULL;
2115 PyObject *ch = NULL;
Serhiy Storchakade072102017-10-12 22:17:46 +03002116 PyObject *seq = NULL, *ei = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 PyObject *result = NULL;
2118 struct kevent *evl = NULL;
2119 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002120 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002122 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 if (self->kqfd < 0)
2125 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2128 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 if (nevents < 0) {
2131 PyErr_Format(PyExc_ValueError,
2132 "Length of eventlist must be 0 or positive, got %d",
2133 nevents);
2134 return NULL;
2135 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 if (otimeout == Py_None || otimeout == NULL) {
2138 ptimeoutspec = NULL;
2139 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002140 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002141 if (_PyTime_FromSecondsObject(&timeout,
Pablo Galindo2c15b292017-10-17 15:14:41 +01002142 otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002143 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002144 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002145 "or None, got %.200s",
2146 Py_TYPE(otimeout)->tp_name);
2147 return NULL;
2148 }
2149
Victor Stinner4448c082015-03-31 11:48:34 +02002150 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002151 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002152
Victor Stinner4448c082015-03-31 11:48:34 +02002153 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 PyErr_SetString(PyExc_ValueError,
2155 "timeout must be positive or None");
2156 return NULL;
2157 }
Victor Stinner4448c082015-03-31 11:48:34 +02002158 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 if (ch != NULL && ch != Py_None) {
Serhiy Storchakade072102017-10-12 22:17:46 +03002162 seq = PySequence_Fast(ch, "changelist is not iterable");
2163 if (seq == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 return NULL;
2165 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002166 if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
2167 PyErr_SetString(PyExc_OverflowError,
2168 "changelist is too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 goto error;
2170 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002171 nchanges = (int)PySequence_Fast_GET_SIZE(seq);
Georg Brandlc0e22b72010-03-14 10:51:01 +00002172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 chl = PyMem_New(struct kevent, nchanges);
2174 if (chl == NULL) {
2175 PyErr_NoMemory();
2176 goto error;
2177 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002178 for (i = 0; i < nchanges; ++i) {
2179 ei = PySequence_Fast_GET_ITEM(seq, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 if (!kqueue_event_Check(ei)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyErr_SetString(PyExc_TypeError,
2182 "changelist must be an iterable of "
2183 "select.kevent objects");
2184 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002186 chl[i] = ((kqueue_event_Object *)ei)->e;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 }
Serhiy Storchakade072102017-10-12 22:17:46 +03002188 Py_CLEAR(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 /* event list */
2192 if (nevents) {
2193 evl = PyMem_New(struct kevent, nevents);
2194 if (evl == NULL) {
2195 PyErr_NoMemory();
2196 goto error;
2197 }
2198 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002199
Victor Stinner4448c082015-03-31 11:48:34 +02002200 if (ptimeoutspec)
2201 deadline = _PyTime_GetMonotonicClock() + timeout;
2202
2203 do {
2204 Py_BEGIN_ALLOW_THREADS
2205 errno = 0;
2206 gotevents = kevent(self->kqfd, chl, nchanges,
2207 evl, nevents, ptimeoutspec);
2208 Py_END_ALLOW_THREADS
2209
2210 if (errno != EINTR)
2211 break;
2212
2213 /* kevent() was interrupted by a signal */
2214 if (PyErr_CheckSignals())
2215 goto error;
2216
2217 if (ptimeoutspec) {
2218 timeout = deadline - _PyTime_GetMonotonicClock();
2219 if (timeout < 0) {
2220 gotevents = 0;
2221 break;
2222 }
2223 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2224 goto error;
2225 /* retry kevent() with the recomputed timeout */
2226 }
2227 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 if (gotevents == -1) {
2230 PyErr_SetFromErrno(PyExc_OSError);
2231 goto error;
2232 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 result = PyList_New(gotevents);
2235 if (result == NULL) {
2236 goto error;
2237 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 for (i = 0; i < gotevents; i++) {
2240 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2243 if (ch == NULL) {
2244 goto error;
2245 }
2246 ch->e = evl[i];
2247 PyList_SET_ITEM(result, i, (PyObject *)ch);
2248 }
2249 PyMem_Free(chl);
2250 PyMem_Free(evl);
2251 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002252
2253 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 PyMem_Free(chl);
2255 PyMem_Free(evl);
2256 Py_XDECREF(result);
Serhiy Storchakade072102017-10-12 22:17:46 +03002257 Py_XDECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002259}
2260
2261PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002262"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002263\n\
2264Calls the kernel kevent function.\n\
Serhiy Storchakade072102017-10-12 22:17:46 +03002265- changelist must be an iterable of kevent objects describing the changes\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002266 to be made to the kernel's watch list or None.\n\
2267- max_events lets you specify the maximum number of events that the\n\
2268 kernel will return.\n\
2269- timeout is the maximum time to wait in seconds, or else None,\n\
2270 to wait forever. timeout accepts floats for smaller timeouts, too.");
2271
2272
2273static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2275 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2276 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2277 kqueue_queue_close_doc},
2278 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2279 kqueue_queue_fileno_doc},
2280 {"control", (PyCFunction)kqueue_queue_control,
2281 METH_VARARGS , kqueue_queue_control_doc},
2282 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002283};
2284
2285static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 {"closed", (getter)kqueue_queue_get_closed, NULL,
2287 "True if the kqueue handler is closed"},
2288 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002289};
2290
2291PyDoc_STRVAR(kqueue_queue_doc,
2292"Kqueue syscall wrapper.\n\
2293\n\
2294For example, to start watching a socket for input:\n\
2295>>> kq = kqueue()\n\
2296>>> sock = socket()\n\
2297>>> sock.connect((host, port))\n\
2298>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2299\n\
2300To wait one second for it to become writeable:\n\
2301>>> kq.control(None, 1, 1000)\n\
2302\n\
2303To stop listening:\n\
2304>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2305
2306static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 PyVarObject_HEAD_INIT(NULL, 0)
2308 "select.kqueue", /* tp_name */
2309 sizeof(kqueue_queue_Object), /* tp_basicsize */
2310 0, /* tp_itemsize */
2311 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2312 0, /* tp_print */
2313 0, /* tp_getattr */
2314 0, /* tp_setattr */
2315 0, /* tp_reserved */
2316 0, /* tp_repr */
2317 0, /* tp_as_number */
2318 0, /* tp_as_sequence */
2319 0, /* tp_as_mapping */
2320 0, /* tp_hash */
2321 0, /* tp_call */
2322 0, /* tp_str */
2323 0, /* tp_getattro */
2324 0, /* tp_setattro */
2325 0, /* tp_as_buffer */
2326 Py_TPFLAGS_DEFAULT, /* tp_flags */
2327 kqueue_queue_doc, /* tp_doc */
2328 0, /* tp_traverse */
2329 0, /* tp_clear */
2330 0, /* tp_richcompare */
2331 0, /* tp_weaklistoffset */
2332 0, /* tp_iter */
2333 0, /* tp_iternext */
2334 kqueue_queue_methods, /* tp_methods */
2335 0, /* tp_members */
2336 kqueue_queue_getsetlist, /* tp_getset */
2337 0, /* tp_base */
2338 0, /* tp_dict */
2339 0, /* tp_descr_get */
2340 0, /* tp_descr_set */
2341 0, /* tp_dictoffset */
2342 0, /* tp_init */
2343 0, /* tp_alloc */
2344 kqueue_queue_new, /* tp_new */
2345 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002346};
2347
2348#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002349
2350
2351
2352
2353
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002354/* ************************************************************************ */
2355
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002356PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002357"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2358\n\
2359Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002360The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002361rlist -- wait until ready for reading\n\
2362wlist -- wait until ready for writing\n\
2363xlist -- wait for an ``exceptional condition''\n\
2364If only one kind of condition is required, pass [] for the other lists.\n\
2365A file descriptor is either a socket or file object, or a small integer\n\
2366gotten from a fileno() method call on one of those.\n\
2367\n\
2368The optional 4th argument specifies a timeout in seconds; it may be\n\
2369a floating point number to specify fractions of seconds. If it is absent\n\
2370or None, the call will never time out.\n\
2371\n\
2372The return value is a tuple of three lists corresponding to the first three\n\
2373arguments; each contains the subset of the corresponding file descriptors\n\
2374that are ready.\n\
2375\n\
2376*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002377On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002378descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002379
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002380static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002382#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002384#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002385#ifdef HAVE_SYS_DEVPOLL_H
2386 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2387#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002389};
2390
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002391PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002392"This module supports asynchronous I/O on multiple file descriptors.\n\
2393\n\
2394*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002395On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002396
Martin v. Löwis1a214512008-06-11 05:26:20 +00002397
2398static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 PyModuleDef_HEAD_INIT,
2400 "select",
2401 module_doc,
2402 -1,
2403 select_methods,
2404 NULL,
2405 NULL,
2406 NULL,
2407 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002408};
2409
Jesus Cead8b9ae62011-11-14 19:07:41 +01002410
2411
2412
Mark Hammond62b1ab12002-07-23 06:31:15 +00002413PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002414PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 PyObject *m;
2417 m = PyModule_Create(&selectmodule);
2418 if (m == NULL)
2419 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002420
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002421 Py_INCREF(PyExc_OSError);
2422 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002423
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002424#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002425#ifdef HAVE_BROKEN_PIPE_BUF
2426#undef PIPE_BUF
2427#define PIPE_BUF 512
2428#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002429 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002430#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002431
Charles-François Natali986a56c2013-01-19 12:19:10 +01002432#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002433#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 if (select_have_broken_poll()) {
2435 if (PyObject_DelAttrString(m, "poll") == -1) {
2436 PyErr_Clear();
2437 }
2438 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002439#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002441#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 if (PyType_Ready(&poll_Type) < 0)
2443 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002444 PyModule_AddIntMacro(m, POLLIN);
2445 PyModule_AddIntMacro(m, POLLPRI);
2446 PyModule_AddIntMacro(m, POLLOUT);
2447 PyModule_AddIntMacro(m, POLLERR);
2448 PyModule_AddIntMacro(m, POLLHUP);
2449 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002450
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002451#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002452 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002453#endif
2454#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002455 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002456#endif
2457#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002458 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002459#endif
2460#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002461 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002462#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002463#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002464 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002465#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002466#ifdef POLLRDHUP
2467 /* Kernel 2.6.17+ */
2468 PyModule_AddIntMacro(m, POLLRDHUP);
2469#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002471#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002472
Jesus Cead8b9ae62011-11-14 19:07:41 +01002473#ifdef HAVE_SYS_DEVPOLL_H
2474 if (PyType_Ready(&devpoll_Type) < 0)
2475 return NULL;
2476#endif
2477
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002478#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2480 if (PyType_Ready(&pyEpoll_Type) < 0)
2481 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 Py_INCREF(&pyEpoll_Type);
2484 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002485
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002486 PyModule_AddIntMacro(m, EPOLLIN);
2487 PyModule_AddIntMacro(m, EPOLLOUT);
2488 PyModule_AddIntMacro(m, EPOLLPRI);
2489 PyModule_AddIntMacro(m, EPOLLERR);
2490 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002491#ifdef EPOLLRDHUP
2492 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002493 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002494#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002495 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002496#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002497 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002498 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002499#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002500#ifdef EPOLLEXCLUSIVE
2501 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2502#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002503
2504#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002505 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002506#endif
2507#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002508 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002509#endif
2510#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002511 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002512#endif
2513#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002514 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002515#endif
2516#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002517 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002518#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002519
Benjamin Peterson95c16622011-12-27 15:36:32 -06002520#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002521 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002522#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002523#endif /* HAVE_EPOLL */
2524
2525#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 kqueue_event_Type.tp_new = PyType_GenericNew;
2527 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2528 if(PyType_Ready(&kqueue_event_Type) < 0)
2529 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 Py_INCREF(&kqueue_event_Type);
2532 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2535 if(PyType_Ready(&kqueue_queue_Type) < 0)
2536 return NULL;
2537 Py_INCREF(&kqueue_queue_Type);
2538 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2539
2540 /* event filters */
2541 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2542 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002543#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002544 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002545#endif
2546#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002548#endif
2549#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002551#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002552#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002553 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002554#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002555#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002557#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 /* event flags */
2561 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2562 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2563 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2564 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2565 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2566 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002567
Berker Peksag7ec64562016-09-14 18:16:59 +03002568#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002570#endif
2571#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2576 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002579#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002580 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002581#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002584#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2586 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2587 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2588 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2589 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2590 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2591 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002592#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002595#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002596 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2597 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2598 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2599 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2600 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2604 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002605#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606
2607 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002608#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2610 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2611 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002612#endif
2613
2614#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002616}