blob: 47da49399f737dd1affa0b6c7786de0bfcfb6380 [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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 int i;
72 for (i = 0; i < 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;
86 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 */
123 if (index >= FD_SETSIZE) {
124 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,
216 _PyTime_ROUND_CEILING) < 0) {
217 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
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200224 if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_CEILING) == -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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 self->ufd_len = PyDict_Size(self->dict);
357 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
434 Py_INCREF(Py_None);
435 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000436}
437
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000438PyDoc_STRVAR(poll_modify_doc,
439"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000440Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000441fd -- either an integer, or an object with a fileno() method returning an\n\
442 int.\n\
443events -- an optional bitmask describing the type of events to check for");
444
445static PyObject *
446poll_modify(pollObject *self, PyObject *args)
447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200449 int fd;
450 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000452
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200453 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 fd = PyObject_AsFileDescriptor(o);
457 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 /* Modify registered fd */
460 key = PyLong_FromLong(fd);
461 if (key == NULL)
462 return NULL;
463 if (PyDict_GetItem(self->dict, key) == NULL) {
464 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200465 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200466 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 return NULL;
468 }
469 value = PyLong_FromLong(events);
470 if (value == NULL) {
471 Py_DECREF(key);
472 return NULL;
473 }
474 err = PyDict_SetItem(self->dict, key, value);
475 Py_DECREF(key);
476 Py_DECREF(value);
477 if (err < 0)
478 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 self->ufd_uptodate = 0;
481
482 Py_INCREF(Py_None);
483 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000484}
485
486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000487PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000489Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000490
491static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 PyObject *key;
495 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 fd = PyObject_AsFileDescriptor( o );
498 if (fd == -1)
499 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 /* Check whether the fd is already in the array */
502 key = PyLong_FromLong(fd);
503 if (key == NULL)
504 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 if (PyDict_DelItem(self->dict, key) == -1) {
507 Py_DECREF(key);
508 /* This will simply raise the KeyError set by PyDict_DelItem
509 if the file descriptor isn't registered. */
510 return NULL;
511 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 Py_DECREF(key);
514 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 Py_INCREF(Py_None);
517 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518}
519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
522Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000523any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000524
525static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000527{
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200528 PyObject *result_list = NULL, *timeout_obj = NULL;
529 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 PyObject *value = NULL, *num = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200531 _PyTime_t timeout, ms, deadline;
532 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200534 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 return NULL;
536 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 /* Check values for timeout */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200539 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 timeout = -1;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200541 ms = -1;
Victor Stinner41eba222015-03-30 21:59:21 +0200542 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 }
544 else {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200545 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
546 _PyTime_ROUND_CEILING) < 0) {
547 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
548 PyErr_SetString(PyExc_TypeError,
549 "timeout must be an integer or None");
550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200552 }
553
554 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
555 if (ms < INT_MIN || ms > INT_MAX) {
556 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200558 }
559
560 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000562
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300563 /* Avoid concurrent poll() invocation, issue 8865 */
564 if (self->poll_running) {
565 PyErr_SetString(PyExc_RuntimeError,
566 "concurrent poll() invocation");
567 return NULL;
568 }
569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 /* Ensure the ufd array is up to date */
571 if (!self->ufd_uptodate)
572 if (update_ufd_array(self) == 0)
573 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000574
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300575 self->poll_running = 1;
576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200578 async_err = 0;
579 do {
580 Py_BEGIN_ALLOW_THREADS
581 errno = 0;
582 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
583 Py_END_ALLOW_THREADS
584
585 if (errno != EINTR)
586 break;
587
588 /* poll() was interrupted by a signal */
589 if (PyErr_CheckSignals()) {
590 async_err = 1;
591 break;
592 }
593
594 if (timeout >= 0) {
595 timeout = deadline - _PyTime_GetMonotonicClock();
596 if (timeout < 0) {
597 poll_result = 0;
598 break;
599 }
600 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
601 /* retry poll() with the recomputed timeout */
602 }
603 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000604
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300605 self->poll_running = 0;
606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200608 if (!async_err)
609 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 return NULL;
611 }
612
613 /* build the result list */
614
615 result_list = PyList_New(poll_result);
616 if (!result_list)
617 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200619 for (i = 0, j = 0; j < poll_result; j++) {
620 /* skip to the next fired descriptor */
621 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 i++;
623 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200624 /* if we hit a NULL return, set value to NULL
625 and break out of loop; code at end will
626 clean up result_list */
627 value = PyTuple_New(2);
628 if (value == NULL)
629 goto error;
630 num = PyLong_FromLong(self->ufds[i].fd);
631 if (num == NULL) {
632 Py_DECREF(value);
633 goto error;
634 }
635 PyTuple_SET_ITEM(value, 0, num);
636
637 /* The &0xffff is a workaround for AIX. 'revents'
638 is a 16-bit short, and IBM assigned POLLNVAL
639 to be 0x8000, so the conversion to int results
640 in a negative number. See SF bug #923315. */
641 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
642 if (num == NULL) {
643 Py_DECREF(value);
644 goto error;
645 }
646 PyTuple_SET_ITEM(value, 1, num);
647 if ((PyList_SetItem(result_list, j, value)) == -1) {
648 Py_DECREF(value);
649 goto error;
650 }
651 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 }
653 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654
655 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 Py_DECREF(result_list);
657 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658}
659
660static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 {"register", (PyCFunction)poll_register,
662 METH_VARARGS, poll_register_doc},
663 {"modify", (PyCFunction)poll_modify,
664 METH_VARARGS, poll_modify_doc},
665 {"unregister", (PyCFunction)poll_unregister,
666 METH_O, poll_unregister_doc},
667 {"poll", (PyCFunction)poll_poll,
668 METH_VARARGS, poll_poll_doc},
669 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000670};
671
672static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000673newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 pollObject *self;
676 self = PyObject_New(pollObject, &poll_Type);
677 if (self == NULL)
678 return NULL;
679 /* ufd_uptodate is a Boolean, denoting whether the
680 array pointed to by ufds matches the contents of the dictionary. */
681 self->ufd_uptodate = 0;
682 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300683 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 self->dict = PyDict_New();
685 if (self->dict == NULL) {
686 Py_DECREF(self);
687 return NULL;
688 }
689 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000690}
691
692static void
693poll_dealloc(pollObject *self)
694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 if (self->ufds != NULL)
696 PyMem_DEL(self->ufds);
697 Py_XDECREF(self->dict);
698 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000699}
700
Tim Peters0c322792002-07-17 16:49:03 +0000701static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 /* The ob_type field must be initialized in the module init function
703 * to be portable to Windows without using C++. */
704 PyVarObject_HEAD_INIT(NULL, 0)
705 "select.poll", /*tp_name*/
706 sizeof(pollObject), /*tp_basicsize*/
707 0, /*tp_itemsize*/
708 /* methods */
709 (destructor)poll_dealloc, /*tp_dealloc*/
710 0, /*tp_print*/
711 0, /*tp_getattr*/
712 0, /*tp_setattr*/
713 0, /*tp_reserved*/
714 0, /*tp_repr*/
715 0, /*tp_as_number*/
716 0, /*tp_as_sequence*/
717 0, /*tp_as_mapping*/
718 0, /*tp_hash*/
719 0, /*tp_call*/
720 0, /*tp_str*/
721 0, /*tp_getattro*/
722 0, /*tp_setattro*/
723 0, /*tp_as_buffer*/
724 Py_TPFLAGS_DEFAULT, /*tp_flags*/
725 0, /*tp_doc*/
726 0, /*tp_traverse*/
727 0, /*tp_clear*/
728 0, /*tp_richcompare*/
729 0, /*tp_weaklistoffset*/
730 0, /*tp_iter*/
731 0, /*tp_iternext*/
732 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000733};
734
Jesus Cead8b9ae62011-11-14 19:07:41 +0100735#ifdef HAVE_SYS_DEVPOLL_H
736typedef struct {
737 PyObject_HEAD
738 int fd_devpoll;
739 int max_n_fds;
740 int n_fds;
741 struct pollfd *fds;
742} devpollObject;
743
744static PyTypeObject devpoll_Type;
745
Victor Stinner13423c32013-08-22 00:19:50 +0200746static PyObject *
747devpoll_err_closed(void)
748{
749 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
750 return NULL;
751}
752
Jesus Cead8b9ae62011-11-14 19:07:41 +0100753static int devpoll_flush(devpollObject *self)
754{
755 int size, n;
756
757 if (!self->n_fds) return 0;
758
759 size = sizeof(struct pollfd)*self->n_fds;
760 self->n_fds = 0;
761
Victor Stinner54799672015-03-19 23:33:09 +0100762 n = _Py_write(self->fd_devpoll, self->fds, size);
763 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100764 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100765
Jesus Cead8b9ae62011-11-14 19:07:41 +0100766 if (n < size) {
767 /*
768 ** Data writed to /dev/poll is a binary data structure. It is not
769 ** clear what to do if a partial write occurred. For now, raise
770 ** an exception and see if we actually found this problem in
771 ** the wild.
772 ** See http://bugs.python.org/issue6397.
773 */
774 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
775 "Please, report at http://bugs.python.org/. "
776 "Data to report: Size tried: %d, actual size written: %d.",
777 size, n);
778 return -1;
779 }
780 return 0;
781}
782
783static PyObject *
784internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
785{
786 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200787 int fd;
788 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100789
Victor Stinner13423c32013-08-22 00:19:50 +0200790 if (self->fd_devpoll < 0)
791 return devpoll_err_closed();
792
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200793 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100794 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100795
796 fd = PyObject_AsFileDescriptor(o);
797 if (fd == -1) return NULL;
798
799 if (remove) {
800 self->fds[self->n_fds].fd = fd;
801 self->fds[self->n_fds].events = POLLREMOVE;
802
803 if (++self->n_fds == self->max_n_fds) {
804 if (devpoll_flush(self))
805 return NULL;
806 }
807 }
808
809 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200810 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100811
812 if (++self->n_fds == self->max_n_fds) {
813 if (devpoll_flush(self))
814 return NULL;
815 }
816
817 Py_RETURN_NONE;
818}
819
820PyDoc_STRVAR(devpoll_register_doc,
821"register(fd [, eventmask] ) -> None\n\n\
822Register a file descriptor with the polling object.\n\
823fd -- either an integer, or an object with a fileno() method returning an\n\
824 int.\n\
825events -- an optional bitmask describing the type of events to check for");
826
827static PyObject *
828devpoll_register(devpollObject *self, PyObject *args)
829{
830 return internal_devpoll_register(self, args, 0);
831}
832
833PyDoc_STRVAR(devpoll_modify_doc,
834"modify(fd[, eventmask]) -> None\n\n\
835Modify a possible already registered file descriptor.\n\
836fd -- either an integer, or an object with a fileno() method returning an\n\
837 int.\n\
838events -- an optional bitmask describing the type of events to check for");
839
840static PyObject *
841devpoll_modify(devpollObject *self, PyObject *args)
842{
843 return internal_devpoll_register(self, args, 1);
844}
845
846
847PyDoc_STRVAR(devpoll_unregister_doc,
848"unregister(fd) -> None\n\n\
849Remove a file descriptor being tracked by the polling object.");
850
851static PyObject *
852devpoll_unregister(devpollObject *self, PyObject *o)
853{
854 int fd;
855
Victor Stinner13423c32013-08-22 00:19:50 +0200856 if (self->fd_devpoll < 0)
857 return devpoll_err_closed();
858
Jesus Cead8b9ae62011-11-14 19:07:41 +0100859 fd = PyObject_AsFileDescriptor( o );
860 if (fd == -1)
861 return NULL;
862
863 self->fds[self->n_fds].fd = fd;
864 self->fds[self->n_fds].events = POLLREMOVE;
865
866 if (++self->n_fds == self->max_n_fds) {
867 if (devpoll_flush(self))
868 return NULL;
869 }
870
871 Py_RETURN_NONE;
872}
873
874PyDoc_STRVAR(devpoll_poll_doc,
875"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
876Polls the set of registered file descriptors, returning a list containing \n\
877any descriptors that have events or errors to report.");
878
879static PyObject *
880devpoll_poll(devpollObject *self, PyObject *args)
881{
882 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200883 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100884 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100885 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200886 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100887
Victor Stinner13423c32013-08-22 00:19:50 +0200888 if (self->fd_devpoll < 0)
889 return devpoll_err_closed();
890
Victor Stinner45ca48b2015-03-31 12:10:33 +0200891 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100892 return NULL;
893 }
894
895 /* Check values for timeout */
Victor Stinner45ca48b2015-03-31 12:10:33 +0200896 if (timeout_obj == NULL || timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100897 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200898 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100899 }
900 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200901 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
902 _PyTime_ROUND_CEILING) < 0) {
903 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
904 PyErr_SetString(PyExc_TypeError,
905 "timeout must be an integer or None");
906 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100907 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200908 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100909
Victor Stinner45ca48b2015-03-31 12:10:33 +0200910 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
911 if (ms < -1 || ms > INT_MAX) {
912 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
913 return NULL;
914 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100915 }
916
917 if (devpoll_flush(self))
918 return NULL;
919
920 dvp.dp_fds = self->fds;
921 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200922 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100923
Victor Stinner45ca48b2015-03-31 12:10:33 +0200924 if (timeout >= 0)
925 deadline = _PyTime_GetMonotonicClock() + timeout;
926
927 do {
928 /* call devpoll() */
929 Py_BEGIN_ALLOW_THREADS
930 errno = 0;
931 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
932 Py_END_ALLOW_THREADS
933
934 if (errno != EINTR)
935 break;
936
937 /* devpoll() was interrupted by a signal */
938 if (PyErr_CheckSignals())
939 return NULL;
940
941 if (timeout >= 0) {
942 timeout = deadline - _PyTime_GetMonotonicClock();
943 if (timeout < 0) {
944 poll_result = 0;
945 break;
946 }
947 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
948 dvp.dp_timeout = (int)ms;
949 /* retry devpoll() with the recomputed timeout */
950 }
951 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100952
953 if (poll_result < 0) {
954 PyErr_SetFromErrno(PyExc_IOError);
955 return NULL;
956 }
957
958 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100959 result_list = PyList_New(poll_result);
960 if (!result_list)
961 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200962
963 for (i = 0; i < poll_result; i++) {
964 num1 = PyLong_FromLong(self->fds[i].fd);
965 num2 = PyLong_FromLong(self->fds[i].revents);
966 if ((num1 == NULL) || (num2 == NULL)) {
967 Py_XDECREF(num1);
968 Py_XDECREF(num2);
969 goto error;
970 }
971 value = PyTuple_Pack(2, num1, num2);
972 Py_DECREF(num1);
973 Py_DECREF(num2);
974 if (value == NULL)
975 goto error;
976 if ((PyList_SetItem(result_list, i, value)) == -1) {
977 Py_DECREF(value);
978 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100979 }
980 }
981
982 return result_list;
983
984 error:
985 Py_DECREF(result_list);
986 return NULL;
987}
988
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100989static int
990devpoll_internal_close(devpollObject *self)
991{
992 int save_errno = 0;
993 if (self->fd_devpoll >= 0) {
994 int fd = self->fd_devpoll;
995 self->fd_devpoll = -1;
996 Py_BEGIN_ALLOW_THREADS
997 if (close(fd) < 0)
998 save_errno = errno;
999 Py_END_ALLOW_THREADS
1000 }
1001 return save_errno;
1002}
1003
Victor Stinner13423c32013-08-22 00:19:50 +02001004static PyObject*
1005devpoll_close(devpollObject *self)
1006{
1007 errno = devpoll_internal_close(self);
1008 if (errno < 0) {
1009 PyErr_SetFromErrno(PyExc_OSError);
1010 return NULL;
1011 }
1012 Py_RETURN_NONE;
1013}
1014
1015PyDoc_STRVAR(devpoll_close_doc,
1016"close() -> None\n\
1017\n\
1018Close the devpoll file descriptor. Further operations on the devpoll\n\
1019object will raise an exception.");
1020
1021static PyObject*
1022devpoll_get_closed(devpollObject *self)
1023{
1024 if (self->fd_devpoll < 0)
1025 Py_RETURN_TRUE;
1026 else
1027 Py_RETURN_FALSE;
1028}
1029
1030static PyObject*
1031devpoll_fileno(devpollObject *self)
1032{
1033 if (self->fd_devpoll < 0)
1034 return devpoll_err_closed();
1035 return PyLong_FromLong(self->fd_devpoll);
1036}
1037
1038PyDoc_STRVAR(devpoll_fileno_doc,
1039"fileno() -> int\n\
1040\n\
1041Return the file descriptor.");
1042
Jesus Cead8b9ae62011-11-14 19:07:41 +01001043static PyMethodDef devpoll_methods[] = {
1044 {"register", (PyCFunction)devpoll_register,
1045 METH_VARARGS, devpoll_register_doc},
1046 {"modify", (PyCFunction)devpoll_modify,
1047 METH_VARARGS, devpoll_modify_doc},
1048 {"unregister", (PyCFunction)devpoll_unregister,
1049 METH_O, devpoll_unregister_doc},
1050 {"poll", (PyCFunction)devpoll_poll,
1051 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +02001052 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
1053 devpoll_close_doc},
1054 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
1055 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +01001056 {NULL, NULL} /* sentinel */
1057};
1058
Victor Stinner13423c32013-08-22 00:19:50 +02001059static PyGetSetDef devpoll_getsetlist[] = {
1060 {"closed", (getter)devpoll_get_closed, NULL,
1061 "True if the devpoll object is closed"},
1062 {0},
1063};
1064
Jesus Cead8b9ae62011-11-14 19:07:41 +01001065static devpollObject *
1066newDevPollObject(void)
1067{
1068 devpollObject *self;
1069 int fd_devpoll, limit_result;
1070 struct pollfd *fds;
1071 struct rlimit limit;
1072
Jesus Cead8b9ae62011-11-14 19:07:41 +01001073 /*
1074 ** If we try to process more that getrlimit()
1075 ** fds, the kernel will give an error, so
1076 ** we set the limit here. It is a dynamic
1077 ** value, because we can change rlimit() anytime.
1078 */
1079 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001080 if (limit_result == -1) {
1081 PyErr_SetFromErrno(PyExc_OSError);
1082 return NULL;
1083 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001084
1085 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1086 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001087 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001088
1089 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1090 if (fds == NULL) {
1091 close(fd_devpoll);
1092 PyErr_NoMemory();
1093 return NULL;
1094 }
1095
1096 self = PyObject_New(devpollObject, &devpoll_Type);
1097 if (self == NULL) {
1098 close(fd_devpoll);
1099 PyMem_DEL(fds);
1100 return NULL;
1101 }
1102 self->fd_devpoll = fd_devpoll;
1103 self->max_n_fds = limit.rlim_cur;
1104 self->n_fds = 0;
1105 self->fds = fds;
1106
1107 return self;
1108}
1109
1110static void
1111devpoll_dealloc(devpollObject *self)
1112{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001113 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001114 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001115 PyObject_Del(self);
1116}
1117
1118static PyTypeObject devpoll_Type = {
1119 /* The ob_type field must be initialized in the module init function
1120 * to be portable to Windows without using C++. */
1121 PyVarObject_HEAD_INIT(NULL, 0)
1122 "select.devpoll", /*tp_name*/
1123 sizeof(devpollObject), /*tp_basicsize*/
1124 0, /*tp_itemsize*/
1125 /* methods */
1126 (destructor)devpoll_dealloc, /*tp_dealloc*/
1127 0, /*tp_print*/
1128 0, /*tp_getattr*/
1129 0, /*tp_setattr*/
1130 0, /*tp_reserved*/
1131 0, /*tp_repr*/
1132 0, /*tp_as_number*/
1133 0, /*tp_as_sequence*/
1134 0, /*tp_as_mapping*/
1135 0, /*tp_hash*/
1136 0, /*tp_call*/
1137 0, /*tp_str*/
1138 0, /*tp_getattro*/
1139 0, /*tp_setattro*/
1140 0, /*tp_as_buffer*/
1141 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1142 0, /*tp_doc*/
1143 0, /*tp_traverse*/
1144 0, /*tp_clear*/
1145 0, /*tp_richcompare*/
1146 0, /*tp_weaklistoffset*/
1147 0, /*tp_iter*/
1148 0, /*tp_iternext*/
1149 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001150 0, /* tp_members */
1151 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001152};
1153#endif /* HAVE_SYS_DEVPOLL_H */
1154
1155
1156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001157PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001158"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001159unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001160
1161static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001162select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001165}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001166
Jesus Cead8b9ae62011-11-14 19:07:41 +01001167#ifdef HAVE_SYS_DEVPOLL_H
1168PyDoc_STRVAR(devpoll_doc,
1169"Returns a polling object, which supports registering and\n\
1170unregistering file descriptors, and then polling them for I/O events.");
1171
1172static PyObject *
1173select_devpoll(PyObject *self, PyObject *unused)
1174{
1175 return (PyObject *)newDevPollObject();
1176}
1177#endif
1178
1179
Thomas Wouters477c8d52006-05-27 19:21:47 +00001180#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182 * On some systems poll() sets errno on invalid file descriptors. We test
1183 * for this at runtime because this bug may be fixed or introduced between
1184 * OS releases.
1185 */
1186static int select_have_broken_poll(void)
1187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 int poll_test;
1189 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 /* Create a file descriptor to make invalid */
1194 if (pipe(filedes) < 0) {
1195 return 1;
1196 }
1197 poll_struct.fd = filedes[0];
1198 close(filedes[0]);
1199 close(filedes[1]);
1200 poll_test = poll(&poll_struct, 1, 0);
1201 if (poll_test < 0) {
1202 return 1;
1203 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1204 return 1;
1205 }
1206 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001207}
1208#endif /* __APPLE__ */
1209
1210#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001211
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001212#ifdef HAVE_EPOLL
1213/* **************************************************************************
1214 * epoll interface for Linux 2.6
1215 *
1216 * Written by Christian Heimes
1217 * Inspired by Twisted's _epoll.pyx and select.poll()
1218 */
1219
1220#ifdef HAVE_SYS_EPOLL_H
1221#include <sys/epoll.h>
1222#endif
1223
1224typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001226 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001227} pyEpoll_Object;
1228
1229static PyTypeObject pyEpoll_Type;
1230#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1231
1232static PyObject *
1233pyepoll_err_closed(void)
1234{
Victor Stinner13423c32013-08-22 00:19:50 +02001235 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001237}
1238
1239static int
1240pyepoll_internal_close(pyEpoll_Object *self)
1241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 int save_errno = 0;
1243 if (self->epfd >= 0) {
1244 int epfd = self->epfd;
1245 self->epfd = -1;
1246 Py_BEGIN_ALLOW_THREADS
1247 if (close(epfd) < 0)
1248 save_errno = errno;
1249 Py_END_ALLOW_THREADS
1250 }
1251 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001252}
1253
1254static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001255newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 assert(type != NULL && type->tp_alloc != NULL);
1260 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1261 if (self == NULL)
1262 return NULL;
1263
1264 if (fd == -1) {
1265 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001266#ifdef HAVE_EPOLL_CREATE1
Victor Stinnerdaf45552013-08-28 00:53:59 +02001267 flags |= EPOLL_CLOEXEC;
Benjamin Peterson83251c12011-12-27 16:01:21 -06001268 if (flags)
1269 self->epfd = epoll_create1(flags);
1270 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001271#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001272 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 Py_END_ALLOW_THREADS
1274 }
1275 else {
1276 self->epfd = fd;
1277 }
1278 if (self->epfd < 0) {
1279 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001280 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 return NULL;
1282 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001283
1284#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001285 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001286 Py_DECREF(self);
1287 return NULL;
1288 }
1289#endif
1290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001292}
1293
1294
1295static PyObject *
1296pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1297{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001298 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001299 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001300
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001301 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1302 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001304 if (sizehint < 0) {
1305 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1306 return NULL;
1307 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001308
Benjamin Peterson95c16622011-12-27 15:36:32 -06001309 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001310}
1311
1312
1313static void
1314pyepoll_dealloc(pyEpoll_Object *self)
1315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 (void)pyepoll_internal_close(self);
1317 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001318}
1319
1320static PyObject*
1321pyepoll_close(pyEpoll_Object *self)
1322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 errno = pyepoll_internal_close(self);
1324 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001325 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 return NULL;
1327 }
1328 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001329}
1330
1331PyDoc_STRVAR(pyepoll_close_doc,
1332"close() -> None\n\
1333\n\
1334Close the epoll control file descriptor. Further operations on the epoll\n\
1335object will raise an exception.");
1336
1337static PyObject*
1338pyepoll_get_closed(pyEpoll_Object *self)
1339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if (self->epfd < 0)
1341 Py_RETURN_TRUE;
1342 else
1343 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001344}
1345
1346static PyObject*
1347pyepoll_fileno(pyEpoll_Object *self)
1348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 if (self->epfd < 0)
1350 return pyepoll_err_closed();
1351 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001352}
1353
1354PyDoc_STRVAR(pyepoll_fileno_doc,
1355"fileno() -> int\n\
1356\n\
1357Return the epoll control file descriptor.");
1358
1359static PyObject*
1360pyepoll_fromfd(PyObject *cls, PyObject *args)
1361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1365 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001366
Benjamin Peterson95c16622011-12-27 15:36:32 -06001367 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368}
1369
1370PyDoc_STRVAR(pyepoll_fromfd_doc,
1371"fromfd(fd) -> epoll\n\
1372\n\
1373Create an epoll object from a given control fd.");
1374
1375static PyObject *
1376pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 struct epoll_event ev;
1379 int result;
1380 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 if (epfd < 0)
1383 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 fd = PyObject_AsFileDescriptor(pfd);
1386 if (fd == -1) {
1387 return NULL;
1388 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389
Guido van Rossumee07b942013-12-06 17:46:22 -08001390 switch (op) {
1391 case EPOLL_CTL_ADD:
1392 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 ev.events = events;
1394 ev.data.fd = fd;
1395 Py_BEGIN_ALLOW_THREADS
1396 result = epoll_ctl(epfd, op, fd, &ev);
1397 Py_END_ALLOW_THREADS
1398 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001399 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1401 * operation required a non-NULL pointer in event, even
1402 * though this argument is ignored. */
1403 Py_BEGIN_ALLOW_THREADS
1404 result = epoll_ctl(epfd, op, fd, &ev);
1405 if (errno == EBADF) {
1406 /* fd already closed */
1407 result = 0;
1408 errno = 0;
1409 }
1410 Py_END_ALLOW_THREADS
1411 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001412 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 result = -1;
1414 errno = EINVAL;
1415 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001418 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 return NULL;
1420 }
1421 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001422}
1423
1424static PyObject *
1425pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 PyObject *pfd;
1428 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1429 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1432 &pfd, &events)) {
1433 return NULL;
1434 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437}
1438
1439PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001440"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001441\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001442Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001443fd is the target file descriptor of the operation.\n\
1444events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001445is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001446\n\
1447The epoll interface supports all file descriptors that support poll.");
1448
1449static PyObject *
1450pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 PyObject *pfd;
1453 unsigned int events;
1454 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1457 &pfd, &events)) {
1458 return NULL;
1459 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001462}
1463
1464PyDoc_STRVAR(pyepoll_modify_doc,
1465"modify(fd, eventmask) -> None\n\
1466\n\
1467fd is the target file descriptor of the operation\n\
1468events is a bit set composed of the various EPOLL constants");
1469
1470static PyObject *
1471pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 PyObject *pfd;
1474 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1477 &pfd)) {
1478 return NULL;
1479 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001482}
1483
1484PyDoc_STRVAR(pyepoll_unregister_doc,
1485"unregister(fd) -> None\n\
1486\n\
1487fd is the target file descriptor of the operation.");
1488
1489static PyObject *
1490pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1491{
Victor Stinner41eba222015-03-30 21:59:21 +02001492 static char *kwlist[] = {"timeout", "maxevents", NULL};
1493 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 int maxevents = -1;
1495 int nfds, i;
1496 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001497 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001498 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 if (self->epfd < 0)
1501 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001502
Victor Stinner41eba222015-03-30 21:59:21 +02001503 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1504 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 return NULL;
1506 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507
Victor Stinner41eba222015-03-30 21:59:21 +02001508 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001510 ms = -1;
1511 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 }
1513 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001514 /* epoll_wait() has a resolution of 1 millisecond, round towards
1515 infinity to wait at least timeout seconds. */
1516 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
1517 _PyTime_ROUND_CEILING) < 0) {
1518 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1519 PyErr_SetString(PyExc_TypeError,
1520 "timeout must be an integer or None");
1521 }
1522 return NULL;
1523 }
1524
1525 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1526 if (ms < INT_MIN || ms > INT_MAX) {
1527 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1528 return NULL;
1529 }
1530
1531 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001535 maxevents = FD_SETSIZE-1;
1536 }
1537 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyErr_Format(PyExc_ValueError,
1539 "maxevents must be greater than 0, got %d",
1540 maxevents);
1541 return NULL;
1542 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001543
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001544 evs = PyMem_New(struct epoll_event, maxevents);
1545 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001546 PyErr_NoMemory();
1547 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001549
Victor Stinner41eba222015-03-30 21:59:21 +02001550 do {
1551 Py_BEGIN_ALLOW_THREADS
1552 errno = 0;
1553 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1554 Py_END_ALLOW_THREADS
1555
1556 if (errno != EINTR)
1557 break;
1558
1559 /* poll() was interrupted by a signal */
1560 if (PyErr_CheckSignals())
1561 goto error;
1562
1563 if (timeout >= 0) {
1564 timeout = deadline - _PyTime_GetMonotonicClock();
1565 if (timeout < 0) {
1566 nfds = 0;
1567 break;
1568 }
1569 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1570 /* retry epoll_wait() with the recomputed timeout */
1571 }
1572 } while(1);
1573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001575 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 goto error;
1577 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 elist = PyList_New(nfds);
1580 if (elist == NULL) {
1581 goto error;
1582 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001585 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 if (etuple == NULL) {
1587 Py_CLEAR(elist);
1588 goto error;
1589 }
1590 PyList_SET_ITEM(elist, i, etuple);
1591 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001592
Christian Heimesf6cd9672008-03-26 13:45:42 +00001593 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001594 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001596}
1597
1598PyDoc_STRVAR(pyepoll_poll_doc,
1599"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1600\n\
1601Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1602in seconds (as float). -1 makes poll wait indefinitely.\n\
1603Up to maxevents are returned to the caller.");
1604
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001605static PyObject *
1606pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1607{
1608 if (self->epfd < 0)
1609 return pyepoll_err_closed();
1610
1611 Py_INCREF(self);
1612 return (PyObject *)self;
1613}
1614
1615static PyObject *
1616pyepoll_exit(PyObject *self, PyObject *args)
1617{
1618 _Py_IDENTIFIER(close);
1619
1620 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1621}
1622
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001623static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 {"fromfd", (PyCFunction)pyepoll_fromfd,
1625 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1626 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1627 pyepoll_close_doc},
1628 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1629 pyepoll_fileno_doc},
1630 {"modify", (PyCFunction)pyepoll_modify,
1631 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1632 {"register", (PyCFunction)pyepoll_register,
1633 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1634 {"unregister", (PyCFunction)pyepoll_unregister,
1635 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1636 {"poll", (PyCFunction)pyepoll_poll,
1637 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001638 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1639 NULL},
1640 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1641 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001643};
1644
1645static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 {"closed", (getter)pyepoll_get_closed, NULL,
1647 "True if the epoll handler is closed"},
1648 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001649};
1650
1651PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001652"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001653\n\
1654Returns an epolling object\n\
1655\n\
1656sizehint must be a positive integer or -1 for the default size. The\n\
1657sizehint is used to optimize internal data structures. It doesn't limit\n\
1658the maximum number of monitored events.");
1659
1660static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 PyVarObject_HEAD_INIT(NULL, 0)
1662 "select.epoll", /* tp_name */
1663 sizeof(pyEpoll_Object), /* tp_basicsize */
1664 0, /* tp_itemsize */
1665 (destructor)pyepoll_dealloc, /* tp_dealloc */
1666 0, /* tp_print */
1667 0, /* tp_getattr */
1668 0, /* tp_setattr */
1669 0, /* tp_reserved */
1670 0, /* tp_repr */
1671 0, /* tp_as_number */
1672 0, /* tp_as_sequence */
1673 0, /* tp_as_mapping */
1674 0, /* tp_hash */
1675 0, /* tp_call */
1676 0, /* tp_str */
1677 PyObject_GenericGetAttr, /* tp_getattro */
1678 0, /* tp_setattro */
1679 0, /* tp_as_buffer */
1680 Py_TPFLAGS_DEFAULT, /* tp_flags */
1681 pyepoll_doc, /* tp_doc */
1682 0, /* tp_traverse */
1683 0, /* tp_clear */
1684 0, /* tp_richcompare */
1685 0, /* tp_weaklistoffset */
1686 0, /* tp_iter */
1687 0, /* tp_iternext */
1688 pyepoll_methods, /* tp_methods */
1689 0, /* tp_members */
1690 pyepoll_getsetlist, /* tp_getset */
1691 0, /* tp_base */
1692 0, /* tp_dict */
1693 0, /* tp_descr_get */
1694 0, /* tp_descr_set */
1695 0, /* tp_dictoffset */
1696 0, /* tp_init */
1697 0, /* tp_alloc */
1698 pyepoll_new, /* tp_new */
1699 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001700};
1701
1702#endif /* HAVE_EPOLL */
1703
1704#ifdef HAVE_KQUEUE
1705/* **************************************************************************
1706 * kqueue interface for BSD
1707 *
1708 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1709 * All rights reserved.
1710 *
1711 * Redistribution and use in source and binary forms, with or without
1712 * modification, are permitted provided that the following conditions
1713 * are met:
1714 * 1. Redistributions of source code must retain the above copyright
1715 * notice, this list of conditions and the following disclaimer.
1716 * 2. Redistributions in binary form must reproduce the above copyright
1717 * notice, this list of conditions and the following disclaimer in the
1718 * documentation and/or other materials provided with the distribution.
1719 *
1720 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1721 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1722 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1723 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1724 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1725 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1726 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1727 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1728 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1729 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1730 * SUCH DAMAGE.
1731 */
1732
1733#ifdef HAVE_SYS_EVENT_H
1734#include <sys/event.h>
1735#endif
1736
1737PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001738"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001739\n\
1740This object is the equivalent of the struct kevent for the C API.\n\
1741\n\
1742See the kqueue manpage for more detailed information about the meaning\n\
1743of the arguments.\n\
1744\n\
1745One minor note: while you might hope that udata could store a\n\
1746reference to a python object, it cannot, because it is impossible to\n\
1747keep a proper reference count of the object once it's passed into the\n\
1748kernel. Therefore, I have restricted it to only storing an integer. I\n\
1749recommend ignoring it and simply using the 'ident' field to key off\n\
1750of. You could also set up a dictionary on the python side to store a\n\
1751udata->object mapping.");
1752
1753typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 PyObject_HEAD
1755 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001756} kqueue_event_Object;
1757
1758static PyTypeObject kqueue_event_Type;
1759
1760#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1761
1762typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 PyObject_HEAD
1764 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001765} kqueue_queue_Object;
1766
1767static PyTypeObject kqueue_queue_Type;
1768
1769#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1770
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001771#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1772# error uintptr_t does not match void *!
1773#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1774# define T_UINTPTRT T_ULONGLONG
1775# define T_INTPTRT T_LONGLONG
1776# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1777# define UINTPTRT_FMT_UNIT "K"
1778# define INTPTRT_FMT_UNIT "L"
1779#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1780# define T_UINTPTRT T_ULONG
1781# define T_INTPTRT T_LONG
1782# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1783# define UINTPTRT_FMT_UNIT "k"
1784# define INTPTRT_FMT_UNIT "l"
1785#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1786# define T_UINTPTRT T_UINT
1787# define T_INTPTRT T_INT
1788# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1789# define UINTPTRT_FMT_UNIT "I"
1790# define INTPTRT_FMT_UNIT "i"
1791#else
1792# error uintptr_t does not match int, long, or long long!
1793#endif
1794
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001795/*
1796 * kevent is not standard and its members vary across BSDs.
1797 */
1798#if !defined(__OpenBSD__)
Christian Heimesaf01f662013-12-21 16:19:10 +01001799# define IDENT_TYPE T_UINTPTRT
Benjamin Petersonca470632016-09-06 13:47:26 -07001800# define IDENT_CAST intptr_t
Christian Heimesaf01f662013-12-21 16:19:10 +01001801# define DATA_TYPE T_INTPTRT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001802# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Christian Heimesaf01f662013-12-21 16:19:10 +01001803# define IDENT_AsType PyLong_AsUintptr_t
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001804#else
Christian Heimesaf01f662013-12-21 16:19:10 +01001805# define IDENT_TYPE T_UINT
1806# define IDENT_CAST int
1807# define DATA_TYPE T_INT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001808# define DATA_FMT_UNIT "i"
Christian Heimesaf01f662013-12-21 16:19:10 +01001809# define IDENT_AsType PyLong_AsUnsignedLong
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001810#endif
1811
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001812/* Unfortunately, we can't store python objects in udata, because
1813 * kevents in the kernel can be removed without warning, which would
1814 * forever lose the refcount on the object stored with it.
1815 */
1816
1817#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1818static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001819 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 {"filter", T_SHORT, KQ_OFF(e.filter)},
1821 {"flags", T_USHORT, KQ_OFF(e.flags)},
1822 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001823 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1825 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001826};
1827#undef KQ_OFF
1828
1829static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001830
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001831kqueue_event_repr(kqueue_event_Object *s)
1832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 char buf[1024];
1834 PyOS_snprintf(
1835 buf, sizeof(buf),
1836 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1837 "data=0x%zd udata=%p>",
1838 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1839 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1840 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001841}
1842
1843static int
1844kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 PyObject *pfd;
1847 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1848 "data", "udata", NULL};
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001849 static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1854 &pfd, &(self->e.filter), &(self->e.flags),
1855 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1856 return -1;
1857 }
1858
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001859 if (PyLong_Check(pfd)
1860#if IDENT_TYPE == T_UINT
Christian Heimesaf01f662013-12-21 16:19:10 +01001861 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001862#endif
1863 ) {
1864 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 }
1866 else {
1867 self->e.ident = PyObject_AsFileDescriptor(pfd);
1868 }
1869 if (PyErr_Occurred()) {
1870 return -1;
1871 }
1872 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001873}
1874
1875static PyObject *
1876kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001878{
Benjamin Petersonca470632016-09-06 13:47:26 -07001879 intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (!kqueue_event_Check(o)) {
1882 if (op == Py_EQ || op == Py_NE) {
1883 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1884 Py_INCREF(res);
1885 return res;
1886 }
1887 PyErr_Format(PyExc_TypeError,
1888 "can't compare %.200s to %.200s",
1889 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1890 return NULL;
1891 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001892 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 ((result = s->e.filter - o->e.filter) == 0) &&
1894 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001895 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 ((result = s->e.data - o->e.data) == 0) &&
1897 ((result = s->e.udata - o->e.udata) == 0)
1898 ) {
1899 result = 0;
1900 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 switch (op) {
Guido van Rossumee07b942013-12-06 17:46:22 -08001903 case Py_EQ:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 result = (result == 0);
1905 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001906 case Py_NE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 result = (result != 0);
1908 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001909 case Py_LE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 result = (result <= 0);
1911 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001912 case Py_GE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 result = (result >= 0);
1914 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001915 case Py_LT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 result = (result < 0);
1917 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001918 case Py_GT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 result = (result > 0);
1920 break;
1921 }
1922 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001923}
1924
1925static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 PyVarObject_HEAD_INIT(NULL, 0)
1927 "select.kevent", /* tp_name */
1928 sizeof(kqueue_event_Object), /* tp_basicsize */
1929 0, /* tp_itemsize */
1930 0, /* tp_dealloc */
1931 0, /* tp_print */
1932 0, /* tp_getattr */
1933 0, /* tp_setattr */
1934 0, /* tp_reserved */
1935 (reprfunc)kqueue_event_repr, /* tp_repr */
1936 0, /* tp_as_number */
1937 0, /* tp_as_sequence */
1938 0, /* tp_as_mapping */
1939 0, /* tp_hash */
1940 0, /* tp_call */
1941 0, /* tp_str */
1942 0, /* tp_getattro */
1943 0, /* tp_setattro */
1944 0, /* tp_as_buffer */
1945 Py_TPFLAGS_DEFAULT, /* tp_flags */
1946 kqueue_event_doc, /* tp_doc */
1947 0, /* tp_traverse */
1948 0, /* tp_clear */
1949 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1950 0, /* tp_weaklistoffset */
1951 0, /* tp_iter */
1952 0, /* tp_iternext */
1953 0, /* tp_methods */
1954 kqueue_event_members, /* tp_members */
1955 0, /* tp_getset */
1956 0, /* tp_base */
1957 0, /* tp_dict */
1958 0, /* tp_descr_get */
1959 0, /* tp_descr_set */
1960 0, /* tp_dictoffset */
1961 (initproc)kqueue_event_init, /* tp_init */
1962 0, /* tp_alloc */
1963 0, /* tp_new */
1964 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001965};
1966
1967static PyObject *
1968kqueue_queue_err_closed(void)
1969{
Victor Stinner13423c32013-08-22 00:19:50 +02001970 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001972}
1973
1974static int
1975kqueue_queue_internal_close(kqueue_queue_Object *self)
1976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 int save_errno = 0;
1978 if (self->kqfd >= 0) {
1979 int kqfd = self->kqfd;
1980 self->kqfd = -1;
1981 Py_BEGIN_ALLOW_THREADS
1982 if (close(kqfd) < 0)
1983 save_errno = errno;
1984 Py_END_ALLOW_THREADS
1985 }
1986 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001987}
1988
1989static PyObject *
1990newKqueue_Object(PyTypeObject *type, SOCKET fd)
1991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 kqueue_queue_Object *self;
1993 assert(type != NULL && type->tp_alloc != NULL);
1994 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1995 if (self == NULL) {
1996 return NULL;
1997 }
1998
1999 if (fd == -1) {
2000 Py_BEGIN_ALLOW_THREADS
2001 self->kqfd = kqueue();
2002 Py_END_ALLOW_THREADS
2003 }
2004 else {
2005 self->kqfd = fd;
2006 }
2007 if (self->kqfd < 0) {
2008 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002009 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 return NULL;
2011 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002012
2013 if (fd == -1) {
2014 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2015 Py_DECREF(self);
2016 return NULL;
2017 }
2018 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002020}
2021
2022static PyObject *
2023kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 if ((args != NULL && PyObject_Size(args)) ||
2026 (kwds != NULL && PyObject_Size(kwds))) {
2027 PyErr_SetString(PyExc_ValueError,
2028 "select.kqueue doesn't accept arguments");
2029 return NULL;
2030 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033}
2034
2035static void
2036kqueue_queue_dealloc(kqueue_queue_Object *self)
2037{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 kqueue_queue_internal_close(self);
2039 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040}
2041
2042static PyObject*
2043kqueue_queue_close(kqueue_queue_Object *self)
2044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 errno = kqueue_queue_internal_close(self);
2046 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002047 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 return NULL;
2049 }
2050 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002051}
2052
2053PyDoc_STRVAR(kqueue_queue_close_doc,
2054"close() -> None\n\
2055\n\
2056Close the kqueue control file descriptor. Further operations on the kqueue\n\
2057object will raise an exception.");
2058
2059static PyObject*
2060kqueue_queue_get_closed(kqueue_queue_Object *self)
2061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 if (self->kqfd < 0)
2063 Py_RETURN_TRUE;
2064 else
2065 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002066}
2067
2068static PyObject*
2069kqueue_queue_fileno(kqueue_queue_Object *self)
2070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 if (self->kqfd < 0)
2072 return kqueue_queue_err_closed();
2073 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002074}
2075
2076PyDoc_STRVAR(kqueue_queue_fileno_doc,
2077"fileno() -> int\n\
2078\n\
2079Return the kqueue control file descriptor.");
2080
2081static PyObject*
2082kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2087 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002090}
2091
2092PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2093"fromfd(fd) -> kqueue\n\
2094\n\
2095Create a kqueue object from a given control fd.");
2096
2097static PyObject *
2098kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 int nevents = 0;
2101 int gotevents = 0;
2102 int nchanges = 0;
2103 int i = 0;
2104 PyObject *otimeout = NULL;
2105 PyObject *ch = NULL;
2106 PyObject *it = NULL, *ei = NULL;
2107 PyObject *result = NULL;
2108 struct kevent *evl = NULL;
2109 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002110 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002112 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 if (self->kqfd < 0)
2115 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2118 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 if (nevents < 0) {
2121 PyErr_Format(PyExc_ValueError,
2122 "Length of eventlist must be 0 or positive, got %d",
2123 nevents);
2124 return NULL;
2125 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 if (otimeout == Py_None || otimeout == NULL) {
2128 ptimeoutspec = NULL;
2129 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002130 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002131 if (_PyTime_FromSecondsObject(&timeout,
Victor Stinner869e1772015-03-30 03:49:14 +02002132 otimeout, _PyTime_ROUND_CEILING) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002133 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002134 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002135 "or None, got %.200s",
2136 Py_TYPE(otimeout)->tp_name);
2137 return NULL;
2138 }
2139
Victor Stinner4448c082015-03-31 11:48:34 +02002140 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002141 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002142
Victor Stinner4448c082015-03-31 11:48:34 +02002143 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 PyErr_SetString(PyExc_ValueError,
2145 "timeout must be positive or None");
2146 return NULL;
2147 }
Victor Stinner4448c082015-03-31 11:48:34 +02002148 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (ch != NULL && ch != Py_None) {
2152 it = PyObject_GetIter(ch);
2153 if (it == NULL) {
2154 PyErr_SetString(PyExc_TypeError,
2155 "changelist is not iterable");
2156 return NULL;
2157 }
2158 nchanges = PyObject_Size(ch);
2159 if (nchanges < 0) {
2160 goto error;
2161 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00002162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 chl = PyMem_New(struct kevent, nchanges);
2164 if (chl == NULL) {
2165 PyErr_NoMemory();
2166 goto error;
2167 }
2168 i = 0;
2169 while ((ei = PyIter_Next(it)) != NULL) {
2170 if (!kqueue_event_Check(ei)) {
2171 Py_DECREF(ei);
2172 PyErr_SetString(PyExc_TypeError,
2173 "changelist must be an iterable of "
2174 "select.kevent objects");
2175 goto error;
2176 } else {
2177 chl[i++] = ((kqueue_event_Object *)ei)->e;
2178 }
2179 Py_DECREF(ei);
2180 }
2181 }
2182 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 /* event list */
2185 if (nevents) {
2186 evl = PyMem_New(struct kevent, nevents);
2187 if (evl == NULL) {
2188 PyErr_NoMemory();
2189 goto error;
2190 }
2191 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002192
Victor Stinner4448c082015-03-31 11:48:34 +02002193 if (ptimeoutspec)
2194 deadline = _PyTime_GetMonotonicClock() + timeout;
2195
2196 do {
2197 Py_BEGIN_ALLOW_THREADS
2198 errno = 0;
2199 gotevents = kevent(self->kqfd, chl, nchanges,
2200 evl, nevents, ptimeoutspec);
2201 Py_END_ALLOW_THREADS
2202
2203 if (errno != EINTR)
2204 break;
2205
2206 /* kevent() was interrupted by a signal */
2207 if (PyErr_CheckSignals())
2208 goto error;
2209
2210 if (ptimeoutspec) {
2211 timeout = deadline - _PyTime_GetMonotonicClock();
2212 if (timeout < 0) {
2213 gotevents = 0;
2214 break;
2215 }
2216 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2217 goto error;
2218 /* retry kevent() with the recomputed timeout */
2219 }
2220 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 if (gotevents == -1) {
2223 PyErr_SetFromErrno(PyExc_OSError);
2224 goto error;
2225 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 result = PyList_New(gotevents);
2228 if (result == NULL) {
2229 goto error;
2230 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 for (i = 0; i < gotevents; i++) {
2233 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2236 if (ch == NULL) {
2237 goto error;
2238 }
2239 ch->e = evl[i];
2240 PyList_SET_ITEM(result, i, (PyObject *)ch);
2241 }
2242 PyMem_Free(chl);
2243 PyMem_Free(evl);
2244 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002245
2246 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 PyMem_Free(chl);
2248 PyMem_Free(evl);
2249 Py_XDECREF(result);
2250 Py_XDECREF(it);
2251 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002252}
2253
2254PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002255"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002256\n\
2257Calls the kernel kevent function.\n\
2258- changelist must be a list of kevent objects describing the changes\n\
2259 to be made to the kernel's watch list or None.\n\
2260- max_events lets you specify the maximum number of events that the\n\
2261 kernel will return.\n\
2262- timeout is the maximum time to wait in seconds, or else None,\n\
2263 to wait forever. timeout accepts floats for smaller timeouts, too.");
2264
2265
2266static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2268 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2269 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2270 kqueue_queue_close_doc},
2271 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2272 kqueue_queue_fileno_doc},
2273 {"control", (PyCFunction)kqueue_queue_control,
2274 METH_VARARGS , kqueue_queue_control_doc},
2275 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002276};
2277
2278static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 {"closed", (getter)kqueue_queue_get_closed, NULL,
2280 "True if the kqueue handler is closed"},
2281 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002282};
2283
2284PyDoc_STRVAR(kqueue_queue_doc,
2285"Kqueue syscall wrapper.\n\
2286\n\
2287For example, to start watching a socket for input:\n\
2288>>> kq = kqueue()\n\
2289>>> sock = socket()\n\
2290>>> sock.connect((host, port))\n\
2291>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2292\n\
2293To wait one second for it to become writeable:\n\
2294>>> kq.control(None, 1, 1000)\n\
2295\n\
2296To stop listening:\n\
2297>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2298
2299static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002300 PyVarObject_HEAD_INIT(NULL, 0)
2301 "select.kqueue", /* tp_name */
2302 sizeof(kqueue_queue_Object), /* tp_basicsize */
2303 0, /* tp_itemsize */
2304 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2305 0, /* tp_print */
2306 0, /* tp_getattr */
2307 0, /* tp_setattr */
2308 0, /* tp_reserved */
2309 0, /* tp_repr */
2310 0, /* tp_as_number */
2311 0, /* tp_as_sequence */
2312 0, /* tp_as_mapping */
2313 0, /* tp_hash */
2314 0, /* tp_call */
2315 0, /* tp_str */
2316 0, /* tp_getattro */
2317 0, /* tp_setattro */
2318 0, /* tp_as_buffer */
2319 Py_TPFLAGS_DEFAULT, /* tp_flags */
2320 kqueue_queue_doc, /* tp_doc */
2321 0, /* tp_traverse */
2322 0, /* tp_clear */
2323 0, /* tp_richcompare */
2324 0, /* tp_weaklistoffset */
2325 0, /* tp_iter */
2326 0, /* tp_iternext */
2327 kqueue_queue_methods, /* tp_methods */
2328 0, /* tp_members */
2329 kqueue_queue_getsetlist, /* tp_getset */
2330 0, /* tp_base */
2331 0, /* tp_dict */
2332 0, /* tp_descr_get */
2333 0, /* tp_descr_set */
2334 0, /* tp_dictoffset */
2335 0, /* tp_init */
2336 0, /* tp_alloc */
2337 kqueue_queue_new, /* tp_new */
2338 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002339};
2340
2341#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002342
2343
2344
2345
2346
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002347/* ************************************************************************ */
2348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002349PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002350"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2351\n\
2352Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002353The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002354rlist -- wait until ready for reading\n\
2355wlist -- wait until ready for writing\n\
2356xlist -- wait for an ``exceptional condition''\n\
2357If only one kind of condition is required, pass [] for the other lists.\n\
2358A file descriptor is either a socket or file object, or a small integer\n\
2359gotten from a fileno() method call on one of those.\n\
2360\n\
2361The optional 4th argument specifies a timeout in seconds; it may be\n\
2362a floating point number to specify fractions of seconds. If it is absent\n\
2363or None, the call will never time out.\n\
2364\n\
2365The return value is a tuple of three lists corresponding to the first three\n\
2366arguments; each contains the subset of the corresponding file descriptors\n\
2367that are ready.\n\
2368\n\
2369*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002370On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002371descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002372
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002373static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002375#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002377#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002378#ifdef HAVE_SYS_DEVPOLL_H
2379 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2380#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002382};
2383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002385"This module supports asynchronous I/O on multiple file descriptors.\n\
2386\n\
2387*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002388On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002389
Martin v. Löwis1a214512008-06-11 05:26:20 +00002390
2391static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 PyModuleDef_HEAD_INIT,
2393 "select",
2394 module_doc,
2395 -1,
2396 select_methods,
2397 NULL,
2398 NULL,
2399 NULL,
2400 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002401};
2402
Jesus Cead8b9ae62011-11-14 19:07:41 +01002403
2404
2405
Mark Hammond62b1ab12002-07-23 06:31:15 +00002406PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002407PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 PyObject *m;
2410 m = PyModule_Create(&selectmodule);
2411 if (m == NULL)
2412 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002413
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002414 Py_INCREF(PyExc_OSError);
2415 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002416
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002417#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002418#ifdef HAVE_BROKEN_PIPE_BUF
2419#undef PIPE_BUF
2420#define PIPE_BUF 512
2421#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002422 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002423#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002424
Charles-François Natali986a56c2013-01-19 12:19:10 +01002425#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002426#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 if (select_have_broken_poll()) {
2428 if (PyObject_DelAttrString(m, "poll") == -1) {
2429 PyErr_Clear();
2430 }
2431 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002432#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002434#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 if (PyType_Ready(&poll_Type) < 0)
2436 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002437 PyModule_AddIntMacro(m, POLLIN);
2438 PyModule_AddIntMacro(m, POLLPRI);
2439 PyModule_AddIntMacro(m, POLLOUT);
2440 PyModule_AddIntMacro(m, POLLERR);
2441 PyModule_AddIntMacro(m, POLLHUP);
2442 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002443
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002444#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002445 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002446#endif
2447#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002448 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002449#endif
2450#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002451 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002452#endif
2453#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002454 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002455#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002456#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002457 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002458#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002459#ifdef POLLRDHUP
2460 /* Kernel 2.6.17+ */
2461 PyModule_AddIntMacro(m, POLLRDHUP);
2462#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002464#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002465
Jesus Cead8b9ae62011-11-14 19:07:41 +01002466#ifdef HAVE_SYS_DEVPOLL_H
2467 if (PyType_Ready(&devpoll_Type) < 0)
2468 return NULL;
2469#endif
2470
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002471#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2473 if (PyType_Ready(&pyEpoll_Type) < 0)
2474 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 Py_INCREF(&pyEpoll_Type);
2477 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002478
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002479 PyModule_AddIntMacro(m, EPOLLIN);
2480 PyModule_AddIntMacro(m, EPOLLOUT);
2481 PyModule_AddIntMacro(m, EPOLLPRI);
2482 PyModule_AddIntMacro(m, EPOLLERR);
2483 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002484#ifdef EPOLLRDHUP
2485 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002486 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002487#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002488 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002489#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002491 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002492#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002493#ifdef EPOLLEXCLUSIVE
2494 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2495#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002496
2497#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002498 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002499#endif
2500#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002501 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002502#endif
2503#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002504 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002505#endif
2506#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002507 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002508#endif
2509#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002510 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002511#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002512
Benjamin Peterson95c16622011-12-27 15:36:32 -06002513#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002514 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002515#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002516#endif /* HAVE_EPOLL */
2517
2518#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 kqueue_event_Type.tp_new = PyType_GenericNew;
2520 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2521 if(PyType_Ready(&kqueue_event_Type) < 0)
2522 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 Py_INCREF(&kqueue_event_Type);
2525 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2528 if(PyType_Ready(&kqueue_queue_Type) < 0)
2529 return NULL;
2530 Py_INCREF(&kqueue_queue_Type);
2531 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2532
2533 /* event filters */
2534 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2535 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002536#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002537 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002538#endif
2539#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002540 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002541#endif
2542#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002543 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002544#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002545#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002547#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002548#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002549 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002550#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002553 /* event flags */
2554 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2555 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2556 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2557 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2558 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2559 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002560
Berker Peksag7ec64562016-09-14 18:16:59 +03002561#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002562 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002563#endif
2564#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002566#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2569 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002572#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002574#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002576 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002577#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2579 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2580 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2581 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2582 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2583 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2584 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002585#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002588#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2590 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2591 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2592 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2593 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2596 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2597 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002598#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599
2600 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002601#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2604 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002605#endif
2606
2607#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002609}