blob: 0206651669fec9b01001088aa6d0a1a2d034b16e [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
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200356 self->ufd_len = PyDict_GET_SIZE(self->dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
358 if (self->ufds == NULL) {
359 self->ufds = old_ufds;
360 PyErr_NoMemory();
361 return 0;
362 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 i = pos = 0;
365 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200366 assert(i < self->ufd_len);
367 /* Never overflow */
368 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200369 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 i++;
371 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200372 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 self->ufd_uptodate = 1;
374 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000375}
376
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200377static int
378ushort_converter(PyObject *obj, void *ptr)
379{
380 unsigned long uval;
381
382 uval = PyLong_AsUnsignedLong(obj);
383 if (uval == (unsigned long)-1 && PyErr_Occurred())
384 return 0;
385 if (uval > USHRT_MAX) {
386 PyErr_SetString(PyExc_OverflowError,
387 "Python int too large for C unsigned short");
388 return 0;
389 }
390
391 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
392 return 1;
393}
394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000395PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000396"register(fd [, eventmask] ) -> None\n\n\
397Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000398fd -- either an integer, or an object with a fileno() method returning an\n\
399 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000400events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000401
402static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200406 int fd;
407 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200410 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 fd = PyObject_AsFileDescriptor(o);
414 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 /* Add entry to the internal dictionary: the key is the
417 file descriptor, and the value is the event mask. */
418 key = PyLong_FromLong(fd);
419 if (key == NULL)
420 return NULL;
421 value = PyLong_FromLong(events);
422 if (value == NULL) {
423 Py_DECREF(key);
424 return NULL;
425 }
426 err = PyDict_SetItem(self->dict, key, value);
427 Py_DECREF(key);
428 Py_DECREF(value);
429 if (err < 0)
430 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 self->ufd_uptodate = 0;
433
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 *
Berker Peksage2197d12016-09-26 23:30:41 +03001255newPyEpoll_Object(PyTypeObject *type, int sizehint, 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
Berker Peksage2197d12016-09-26 23:30:41 +03001267 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1268#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001269 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001270#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 Py_END_ALLOW_THREADS
1272 }
1273 else {
1274 self->epfd = fd;
1275 }
1276 if (self->epfd < 0) {
1277 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001278 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 return NULL;
1280 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001281
1282#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001283 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001284 Py_DECREF(self);
1285 return NULL;
1286 }
1287#endif
1288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001290}
1291
1292
1293static PyObject *
1294pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1295{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001296 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001297 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001298
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001299 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1300 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001302 if (sizehint < 0) {
1303 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1304 return NULL;
1305 }
Berker Peksage2197d12016-09-26 23:30:41 +03001306 if (flags && flags != EPOLL_CLOEXEC) {
1307 PyErr_SetString(PyExc_OSError, "invalid flags");
1308 return NULL;
1309 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001310
Berker Peksage2197d12016-09-26 23:30:41 +03001311 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001312}
1313
1314
1315static void
1316pyepoll_dealloc(pyEpoll_Object *self)
1317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 (void)pyepoll_internal_close(self);
1319 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001320}
1321
1322static PyObject*
1323pyepoll_close(pyEpoll_Object *self)
1324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 errno = pyepoll_internal_close(self);
1326 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001327 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 return NULL;
1329 }
1330 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001331}
1332
1333PyDoc_STRVAR(pyepoll_close_doc,
1334"close() -> None\n\
1335\n\
1336Close the epoll control file descriptor. Further operations on the epoll\n\
1337object will raise an exception.");
1338
1339static PyObject*
1340pyepoll_get_closed(pyEpoll_Object *self)
1341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 if (self->epfd < 0)
1343 Py_RETURN_TRUE;
1344 else
1345 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001346}
1347
1348static PyObject*
1349pyepoll_fileno(pyEpoll_Object *self)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (self->epfd < 0)
1352 return pyepoll_err_closed();
1353 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001354}
1355
1356PyDoc_STRVAR(pyepoll_fileno_doc,
1357"fileno() -> int\n\
1358\n\
1359Return the epoll control file descriptor.");
1360
1361static PyObject*
1362pyepoll_fromfd(PyObject *cls, PyObject *args)
1363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1367 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001368
Berker Peksage2197d12016-09-26 23:30:41 +03001369 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370}
1371
1372PyDoc_STRVAR(pyepoll_fromfd_doc,
1373"fromfd(fd) -> epoll\n\
1374\n\
1375Create an epoll object from a given control fd.");
1376
1377static PyObject *
1378pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 struct epoll_event ev;
1381 int result;
1382 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 if (epfd < 0)
1385 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 fd = PyObject_AsFileDescriptor(pfd);
1388 if (fd == -1) {
1389 return NULL;
1390 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001391
Guido van Rossumee07b942013-12-06 17:46:22 -08001392 switch (op) {
1393 case EPOLL_CTL_ADD:
1394 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 ev.events = events;
1396 ev.data.fd = fd;
1397 Py_BEGIN_ALLOW_THREADS
1398 result = epoll_ctl(epfd, op, fd, &ev);
1399 Py_END_ALLOW_THREADS
1400 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001401 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1403 * operation required a non-NULL pointer in event, even
1404 * though this argument is ignored. */
1405 Py_BEGIN_ALLOW_THREADS
1406 result = epoll_ctl(epfd, op, fd, &ev);
1407 if (errno == EBADF) {
1408 /* fd already closed */
1409 result = 0;
1410 errno = 0;
1411 }
1412 Py_END_ALLOW_THREADS
1413 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001414 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 result = -1;
1416 errno = EINVAL;
1417 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001420 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 return NULL;
1422 }
1423 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001424}
1425
1426static PyObject *
1427pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 PyObject *pfd;
1430 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1431 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1434 &pfd, &events)) {
1435 return NULL;
1436 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001439}
1440
1441PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001442"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001443\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001444Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001445fd is the target file descriptor of the operation.\n\
1446events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001447is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001448\n\
1449The epoll interface supports all file descriptors that support poll.");
1450
1451static PyObject *
1452pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 PyObject *pfd;
1455 unsigned int events;
1456 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1459 &pfd, &events)) {
1460 return NULL;
1461 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001464}
1465
1466PyDoc_STRVAR(pyepoll_modify_doc,
1467"modify(fd, eventmask) -> None\n\
1468\n\
1469fd is the target file descriptor of the operation\n\
1470events is a bit set composed of the various EPOLL constants");
1471
1472static PyObject *
1473pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 PyObject *pfd;
1476 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1479 &pfd)) {
1480 return NULL;
1481 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001484}
1485
1486PyDoc_STRVAR(pyepoll_unregister_doc,
1487"unregister(fd) -> None\n\
1488\n\
1489fd is the target file descriptor of the operation.");
1490
1491static PyObject *
1492pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1493{
Victor Stinner41eba222015-03-30 21:59:21 +02001494 static char *kwlist[] = {"timeout", "maxevents", NULL};
1495 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 int maxevents = -1;
1497 int nfds, i;
1498 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001499 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001500 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 if (self->epfd < 0)
1503 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001504
Victor Stinner41eba222015-03-30 21:59:21 +02001505 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1506 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 return NULL;
1508 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001509
Victor Stinner41eba222015-03-30 21:59:21 +02001510 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001512 ms = -1;
1513 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 }
1515 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001516 /* epoll_wait() has a resolution of 1 millisecond, round towards
1517 infinity to wait at least timeout seconds. */
1518 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
1519 _PyTime_ROUND_CEILING) < 0) {
1520 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1521 PyErr_SetString(PyExc_TypeError,
1522 "timeout must be an integer or None");
1523 }
1524 return NULL;
1525 }
1526
1527 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1528 if (ms < INT_MIN || ms > INT_MAX) {
1529 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1530 return NULL;
1531 }
1532
1533 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001537 maxevents = FD_SETSIZE-1;
1538 }
1539 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 PyErr_Format(PyExc_ValueError,
1541 "maxevents must be greater than 0, got %d",
1542 maxevents);
1543 return NULL;
1544 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001545
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001546 evs = PyMem_New(struct epoll_event, maxevents);
1547 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001548 PyErr_NoMemory();
1549 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001551
Victor Stinner41eba222015-03-30 21:59:21 +02001552 do {
1553 Py_BEGIN_ALLOW_THREADS
1554 errno = 0;
1555 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1556 Py_END_ALLOW_THREADS
1557
1558 if (errno != EINTR)
1559 break;
1560
1561 /* poll() was interrupted by a signal */
1562 if (PyErr_CheckSignals())
1563 goto error;
1564
1565 if (timeout >= 0) {
1566 timeout = deadline - _PyTime_GetMonotonicClock();
1567 if (timeout < 0) {
1568 nfds = 0;
1569 break;
1570 }
1571 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1572 /* retry epoll_wait() with the recomputed timeout */
1573 }
1574 } while(1);
1575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001577 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 goto error;
1579 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 elist = PyList_New(nfds);
1582 if (elist == NULL) {
1583 goto error;
1584 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001587 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 if (etuple == NULL) {
1589 Py_CLEAR(elist);
1590 goto error;
1591 }
1592 PyList_SET_ITEM(elist, i, etuple);
1593 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001594
Christian Heimesf6cd9672008-03-26 13:45:42 +00001595 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001596 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001598}
1599
1600PyDoc_STRVAR(pyepoll_poll_doc,
1601"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1602\n\
1603Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1604in seconds (as float). -1 makes poll wait indefinitely.\n\
1605Up to maxevents are returned to the caller.");
1606
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001607static PyObject *
1608pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1609{
1610 if (self->epfd < 0)
1611 return pyepoll_err_closed();
1612
1613 Py_INCREF(self);
1614 return (PyObject *)self;
1615}
1616
1617static PyObject *
1618pyepoll_exit(PyObject *self, PyObject *args)
1619{
1620 _Py_IDENTIFIER(close);
1621
1622 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1623}
1624
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001625static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 {"fromfd", (PyCFunction)pyepoll_fromfd,
1627 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1628 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1629 pyepoll_close_doc},
1630 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1631 pyepoll_fileno_doc},
1632 {"modify", (PyCFunction)pyepoll_modify,
1633 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1634 {"register", (PyCFunction)pyepoll_register,
1635 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1636 {"unregister", (PyCFunction)pyepoll_unregister,
1637 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1638 {"poll", (PyCFunction)pyepoll_poll,
1639 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001640 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1641 NULL},
1642 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1643 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001645};
1646
1647static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 {"closed", (getter)pyepoll_get_closed, NULL,
1649 "True if the epoll handler is closed"},
1650 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001651};
1652
1653PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001654"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001655\n\
1656Returns an epolling object\n\
1657\n\
1658sizehint must be a positive integer or -1 for the default size. The\n\
1659sizehint is used to optimize internal data structures. It doesn't limit\n\
1660the maximum number of monitored events.");
1661
1662static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 PyVarObject_HEAD_INIT(NULL, 0)
1664 "select.epoll", /* tp_name */
1665 sizeof(pyEpoll_Object), /* tp_basicsize */
1666 0, /* tp_itemsize */
1667 (destructor)pyepoll_dealloc, /* tp_dealloc */
1668 0, /* tp_print */
1669 0, /* tp_getattr */
1670 0, /* tp_setattr */
1671 0, /* tp_reserved */
1672 0, /* tp_repr */
1673 0, /* tp_as_number */
1674 0, /* tp_as_sequence */
1675 0, /* tp_as_mapping */
1676 0, /* tp_hash */
1677 0, /* tp_call */
1678 0, /* tp_str */
1679 PyObject_GenericGetAttr, /* tp_getattro */
1680 0, /* tp_setattro */
1681 0, /* tp_as_buffer */
1682 Py_TPFLAGS_DEFAULT, /* tp_flags */
1683 pyepoll_doc, /* tp_doc */
1684 0, /* tp_traverse */
1685 0, /* tp_clear */
1686 0, /* tp_richcompare */
1687 0, /* tp_weaklistoffset */
1688 0, /* tp_iter */
1689 0, /* tp_iternext */
1690 pyepoll_methods, /* tp_methods */
1691 0, /* tp_members */
1692 pyepoll_getsetlist, /* tp_getset */
1693 0, /* tp_base */
1694 0, /* tp_dict */
1695 0, /* tp_descr_get */
1696 0, /* tp_descr_set */
1697 0, /* tp_dictoffset */
1698 0, /* tp_init */
1699 0, /* tp_alloc */
1700 pyepoll_new, /* tp_new */
1701 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001702};
1703
1704#endif /* HAVE_EPOLL */
1705
1706#ifdef HAVE_KQUEUE
1707/* **************************************************************************
1708 * kqueue interface for BSD
1709 *
1710 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1711 * All rights reserved.
1712 *
1713 * Redistribution and use in source and binary forms, with or without
1714 * modification, are permitted provided that the following conditions
1715 * are met:
1716 * 1. Redistributions of source code must retain the above copyright
1717 * notice, this list of conditions and the following disclaimer.
1718 * 2. Redistributions in binary form must reproduce the above copyright
1719 * notice, this list of conditions and the following disclaimer in the
1720 * documentation and/or other materials provided with the distribution.
1721 *
1722 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1723 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1724 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1725 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1726 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1727 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1728 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1729 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1730 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1731 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1732 * SUCH DAMAGE.
1733 */
1734
1735#ifdef HAVE_SYS_EVENT_H
1736#include <sys/event.h>
1737#endif
1738
1739PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001740"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741\n\
1742This object is the equivalent of the struct kevent for the C API.\n\
1743\n\
1744See the kqueue manpage for more detailed information about the meaning\n\
1745of the arguments.\n\
1746\n\
1747One minor note: while you might hope that udata could store a\n\
1748reference to a python object, it cannot, because it is impossible to\n\
1749keep a proper reference count of the object once it's passed into the\n\
1750kernel. Therefore, I have restricted it to only storing an integer. I\n\
1751recommend ignoring it and simply using the 'ident' field to key off\n\
1752of. You could also set up a dictionary on the python side to store a\n\
1753udata->object mapping.");
1754
1755typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyObject_HEAD
1757 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001758} kqueue_event_Object;
1759
1760static PyTypeObject kqueue_event_Type;
1761
1762#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1763
1764typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 PyObject_HEAD
1766 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001767} kqueue_queue_Object;
1768
1769static PyTypeObject kqueue_queue_Type;
1770
1771#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1772
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001773#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1774# error uintptr_t does not match void *!
1775#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1776# define T_UINTPTRT T_ULONGLONG
1777# define T_INTPTRT T_LONGLONG
1778# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1779# define UINTPTRT_FMT_UNIT "K"
1780# define INTPTRT_FMT_UNIT "L"
1781#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1782# define T_UINTPTRT T_ULONG
1783# define T_INTPTRT T_LONG
1784# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1785# define UINTPTRT_FMT_UNIT "k"
1786# define INTPTRT_FMT_UNIT "l"
1787#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1788# define T_UINTPTRT T_UINT
1789# define T_INTPTRT T_INT
1790# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1791# define UINTPTRT_FMT_UNIT "I"
1792# define INTPTRT_FMT_UNIT "i"
1793#else
1794# error uintptr_t does not match int, long, or long long!
1795#endif
1796
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001797/*
1798 * kevent is not standard and its members vary across BSDs.
1799 */
1800#if !defined(__OpenBSD__)
Christian Heimesaf01f662013-12-21 16:19:10 +01001801# define IDENT_TYPE T_UINTPTRT
Benjamin Petersonca470632016-09-06 13:47:26 -07001802# define IDENT_CAST intptr_t
Christian Heimesaf01f662013-12-21 16:19:10 +01001803# define DATA_TYPE T_INTPTRT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001804# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Christian Heimesaf01f662013-12-21 16:19:10 +01001805# define IDENT_AsType PyLong_AsUintptr_t
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001806#else
Christian Heimesaf01f662013-12-21 16:19:10 +01001807# define IDENT_TYPE T_UINT
1808# define IDENT_CAST int
1809# define DATA_TYPE T_INT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001810# define DATA_FMT_UNIT "i"
Christian Heimesaf01f662013-12-21 16:19:10 +01001811# define IDENT_AsType PyLong_AsUnsignedLong
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001812#endif
1813
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001814/* Unfortunately, we can't store python objects in udata, because
1815 * kevents in the kernel can be removed without warning, which would
1816 * forever lose the refcount on the object stored with it.
1817 */
1818
1819#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1820static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001821 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 {"filter", T_SHORT, KQ_OFF(e.filter)},
1823 {"flags", T_USHORT, KQ_OFF(e.flags)},
1824 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001825 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1827 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001828};
1829#undef KQ_OFF
1830
1831static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001832
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001833kqueue_event_repr(kqueue_event_Object *s)
1834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 char buf[1024];
1836 PyOS_snprintf(
1837 buf, sizeof(buf),
1838 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1839 "data=0x%zd udata=%p>",
1840 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1841 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1842 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001843}
1844
1845static int
1846kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 PyObject *pfd;
1849 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1850 "data", "udata", NULL};
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001851 static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1856 &pfd, &(self->e.filter), &(self->e.flags),
1857 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1858 return -1;
1859 }
1860
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001861 if (PyLong_Check(pfd)
1862#if IDENT_TYPE == T_UINT
Christian Heimesaf01f662013-12-21 16:19:10 +01001863 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001864#endif
1865 ) {
1866 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 }
1868 else {
1869 self->e.ident = PyObject_AsFileDescriptor(pfd);
1870 }
1871 if (PyErr_Occurred()) {
1872 return -1;
1873 }
1874 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001875}
1876
1877static PyObject *
1878kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880{
Benjamin Petersonca470632016-09-06 13:47:26 -07001881 intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 if (!kqueue_event_Check(o)) {
1884 if (op == Py_EQ || op == Py_NE) {
1885 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1886 Py_INCREF(res);
1887 return res;
1888 }
1889 PyErr_Format(PyExc_TypeError,
1890 "can't compare %.200s to %.200s",
1891 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1892 return NULL;
1893 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001894 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 ((result = s->e.filter - o->e.filter) == 0) &&
1896 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001897 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 ((result = s->e.data - o->e.data) == 0) &&
1899 ((result = s->e.udata - o->e.udata) == 0)
1900 ) {
1901 result = 0;
1902 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 switch (op) {
Guido van Rossumee07b942013-12-06 17:46:22 -08001905 case Py_EQ:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 result = (result == 0);
1907 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001908 case Py_NE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 result = (result != 0);
1910 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001911 case Py_LE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 result = (result <= 0);
1913 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001914 case Py_GE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 result = (result >= 0);
1916 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001917 case Py_LT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 result = (result < 0);
1919 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001920 case Py_GT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 result = (result > 0);
1922 break;
1923 }
1924 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001925}
1926
1927static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 PyVarObject_HEAD_INIT(NULL, 0)
1929 "select.kevent", /* tp_name */
1930 sizeof(kqueue_event_Object), /* tp_basicsize */
1931 0, /* tp_itemsize */
1932 0, /* tp_dealloc */
1933 0, /* tp_print */
1934 0, /* tp_getattr */
1935 0, /* tp_setattr */
1936 0, /* tp_reserved */
1937 (reprfunc)kqueue_event_repr, /* tp_repr */
1938 0, /* tp_as_number */
1939 0, /* tp_as_sequence */
1940 0, /* tp_as_mapping */
1941 0, /* tp_hash */
1942 0, /* tp_call */
1943 0, /* tp_str */
1944 0, /* tp_getattro */
1945 0, /* tp_setattro */
1946 0, /* tp_as_buffer */
1947 Py_TPFLAGS_DEFAULT, /* tp_flags */
1948 kqueue_event_doc, /* tp_doc */
1949 0, /* tp_traverse */
1950 0, /* tp_clear */
1951 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1952 0, /* tp_weaklistoffset */
1953 0, /* tp_iter */
1954 0, /* tp_iternext */
1955 0, /* tp_methods */
1956 kqueue_event_members, /* tp_members */
1957 0, /* tp_getset */
1958 0, /* tp_base */
1959 0, /* tp_dict */
1960 0, /* tp_descr_get */
1961 0, /* tp_descr_set */
1962 0, /* tp_dictoffset */
1963 (initproc)kqueue_event_init, /* tp_init */
1964 0, /* tp_alloc */
1965 0, /* tp_new */
1966 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001967};
1968
1969static PyObject *
1970kqueue_queue_err_closed(void)
1971{
Victor Stinner13423c32013-08-22 00:19:50 +02001972 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001974}
1975
1976static int
1977kqueue_queue_internal_close(kqueue_queue_Object *self)
1978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 int save_errno = 0;
1980 if (self->kqfd >= 0) {
1981 int kqfd = self->kqfd;
1982 self->kqfd = -1;
1983 Py_BEGIN_ALLOW_THREADS
1984 if (close(kqfd) < 0)
1985 save_errno = errno;
1986 Py_END_ALLOW_THREADS
1987 }
1988 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001989}
1990
1991static PyObject *
1992newKqueue_Object(PyTypeObject *type, SOCKET fd)
1993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 kqueue_queue_Object *self;
1995 assert(type != NULL && type->tp_alloc != NULL);
1996 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1997 if (self == NULL) {
1998 return NULL;
1999 }
2000
2001 if (fd == -1) {
2002 Py_BEGIN_ALLOW_THREADS
2003 self->kqfd = kqueue();
2004 Py_END_ALLOW_THREADS
2005 }
2006 else {
2007 self->kqfd = fd;
2008 }
2009 if (self->kqfd < 0) {
2010 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002011 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 return NULL;
2013 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002014
2015 if (fd == -1) {
2016 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2017 Py_DECREF(self);
2018 return NULL;
2019 }
2020 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002022}
2023
2024static PyObject *
2025kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 if ((args != NULL && PyObject_Size(args)) ||
2028 (kwds != NULL && PyObject_Size(kwds))) {
2029 PyErr_SetString(PyExc_ValueError,
2030 "select.kqueue doesn't accept arguments");
2031 return NULL;
2032 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002035}
2036
2037static void
2038kqueue_queue_dealloc(kqueue_queue_Object *self)
2039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 kqueue_queue_internal_close(self);
2041 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002042}
2043
2044static PyObject*
2045kqueue_queue_close(kqueue_queue_Object *self)
2046{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 errno = kqueue_queue_internal_close(self);
2048 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002049 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 return NULL;
2051 }
2052 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002053}
2054
2055PyDoc_STRVAR(kqueue_queue_close_doc,
2056"close() -> None\n\
2057\n\
2058Close the kqueue control file descriptor. Further operations on the kqueue\n\
2059object will raise an exception.");
2060
2061static PyObject*
2062kqueue_queue_get_closed(kqueue_queue_Object *self)
2063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 if (self->kqfd < 0)
2065 Py_RETURN_TRUE;
2066 else
2067 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002068}
2069
2070static PyObject*
2071kqueue_queue_fileno(kqueue_queue_Object *self)
2072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 if (self->kqfd < 0)
2074 return kqueue_queue_err_closed();
2075 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002076}
2077
2078PyDoc_STRVAR(kqueue_queue_fileno_doc,
2079"fileno() -> int\n\
2080\n\
2081Return the kqueue control file descriptor.");
2082
2083static PyObject*
2084kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2085{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2089 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002092}
2093
2094PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2095"fromfd(fd) -> kqueue\n\
2096\n\
2097Create a kqueue object from a given control fd.");
2098
2099static PyObject *
2100kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 int nevents = 0;
2103 int gotevents = 0;
2104 int nchanges = 0;
2105 int i = 0;
2106 PyObject *otimeout = NULL;
2107 PyObject *ch = NULL;
2108 PyObject *it = NULL, *ei = NULL;
2109 PyObject *result = NULL;
2110 struct kevent *evl = NULL;
2111 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002112 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002114 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 if (self->kqfd < 0)
2117 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2120 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 if (nevents < 0) {
2123 PyErr_Format(PyExc_ValueError,
2124 "Length of eventlist must be 0 or positive, got %d",
2125 nevents);
2126 return NULL;
2127 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 if (otimeout == Py_None || otimeout == NULL) {
2130 ptimeoutspec = NULL;
2131 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002132 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002133 if (_PyTime_FromSecondsObject(&timeout,
Victor Stinner869e1772015-03-30 03:49:14 +02002134 otimeout, _PyTime_ROUND_CEILING) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002135 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002136 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002137 "or None, got %.200s",
2138 Py_TYPE(otimeout)->tp_name);
2139 return NULL;
2140 }
2141
Victor Stinner4448c082015-03-31 11:48:34 +02002142 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002143 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002144
Victor Stinner4448c082015-03-31 11:48:34 +02002145 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyErr_SetString(PyExc_ValueError,
2147 "timeout must be positive or None");
2148 return NULL;
2149 }
Victor Stinner4448c082015-03-31 11:48:34 +02002150 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 if (ch != NULL && ch != Py_None) {
2154 it = PyObject_GetIter(ch);
2155 if (it == NULL) {
2156 PyErr_SetString(PyExc_TypeError,
2157 "changelist is not iterable");
2158 return NULL;
2159 }
2160 nchanges = PyObject_Size(ch);
2161 if (nchanges < 0) {
2162 goto error;
2163 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00002164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 chl = PyMem_New(struct kevent, nchanges);
2166 if (chl == NULL) {
2167 PyErr_NoMemory();
2168 goto error;
2169 }
2170 i = 0;
2171 while ((ei = PyIter_Next(it)) != NULL) {
2172 if (!kqueue_event_Check(ei)) {
2173 Py_DECREF(ei);
2174 PyErr_SetString(PyExc_TypeError,
2175 "changelist must be an iterable of "
2176 "select.kevent objects");
2177 goto error;
2178 } else {
2179 chl[i++] = ((kqueue_event_Object *)ei)->e;
2180 }
2181 Py_DECREF(ei);
2182 }
2183 }
2184 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 /* event list */
2187 if (nevents) {
2188 evl = PyMem_New(struct kevent, nevents);
2189 if (evl == NULL) {
2190 PyErr_NoMemory();
2191 goto error;
2192 }
2193 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002194
Victor Stinner4448c082015-03-31 11:48:34 +02002195 if (ptimeoutspec)
2196 deadline = _PyTime_GetMonotonicClock() + timeout;
2197
2198 do {
2199 Py_BEGIN_ALLOW_THREADS
2200 errno = 0;
2201 gotevents = kevent(self->kqfd, chl, nchanges,
2202 evl, nevents, ptimeoutspec);
2203 Py_END_ALLOW_THREADS
2204
2205 if (errno != EINTR)
2206 break;
2207
2208 /* kevent() was interrupted by a signal */
2209 if (PyErr_CheckSignals())
2210 goto error;
2211
2212 if (ptimeoutspec) {
2213 timeout = deadline - _PyTime_GetMonotonicClock();
2214 if (timeout < 0) {
2215 gotevents = 0;
2216 break;
2217 }
2218 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2219 goto error;
2220 /* retry kevent() with the recomputed timeout */
2221 }
2222 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 if (gotevents == -1) {
2225 PyErr_SetFromErrno(PyExc_OSError);
2226 goto error;
2227 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 result = PyList_New(gotevents);
2230 if (result == NULL) {
2231 goto error;
2232 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 for (i = 0; i < gotevents; i++) {
2235 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2238 if (ch == NULL) {
2239 goto error;
2240 }
2241 ch->e = evl[i];
2242 PyList_SET_ITEM(result, i, (PyObject *)ch);
2243 }
2244 PyMem_Free(chl);
2245 PyMem_Free(evl);
2246 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002247
2248 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 PyMem_Free(chl);
2250 PyMem_Free(evl);
2251 Py_XDECREF(result);
2252 Py_XDECREF(it);
2253 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002254}
2255
2256PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002257"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002258\n\
2259Calls the kernel kevent function.\n\
2260- changelist must be a list of kevent objects describing the changes\n\
2261 to be made to the kernel's watch list or None.\n\
2262- max_events lets you specify the maximum number of events that the\n\
2263 kernel will return.\n\
2264- timeout is the maximum time to wait in seconds, or else None,\n\
2265 to wait forever. timeout accepts floats for smaller timeouts, too.");
2266
2267
2268static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2270 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2271 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2272 kqueue_queue_close_doc},
2273 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2274 kqueue_queue_fileno_doc},
2275 {"control", (PyCFunction)kqueue_queue_control,
2276 METH_VARARGS , kqueue_queue_control_doc},
2277 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002278};
2279
2280static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 {"closed", (getter)kqueue_queue_get_closed, NULL,
2282 "True if the kqueue handler is closed"},
2283 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002284};
2285
2286PyDoc_STRVAR(kqueue_queue_doc,
2287"Kqueue syscall wrapper.\n\
2288\n\
2289For example, to start watching a socket for input:\n\
2290>>> kq = kqueue()\n\
2291>>> sock = socket()\n\
2292>>> sock.connect((host, port))\n\
2293>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2294\n\
2295To wait one second for it to become writeable:\n\
2296>>> kq.control(None, 1, 1000)\n\
2297\n\
2298To stop listening:\n\
2299>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2300
2301static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 PyVarObject_HEAD_INIT(NULL, 0)
2303 "select.kqueue", /* tp_name */
2304 sizeof(kqueue_queue_Object), /* tp_basicsize */
2305 0, /* tp_itemsize */
2306 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2307 0, /* tp_print */
2308 0, /* tp_getattr */
2309 0, /* tp_setattr */
2310 0, /* tp_reserved */
2311 0, /* tp_repr */
2312 0, /* tp_as_number */
2313 0, /* tp_as_sequence */
2314 0, /* tp_as_mapping */
2315 0, /* tp_hash */
2316 0, /* tp_call */
2317 0, /* tp_str */
2318 0, /* tp_getattro */
2319 0, /* tp_setattro */
2320 0, /* tp_as_buffer */
2321 Py_TPFLAGS_DEFAULT, /* tp_flags */
2322 kqueue_queue_doc, /* tp_doc */
2323 0, /* tp_traverse */
2324 0, /* tp_clear */
2325 0, /* tp_richcompare */
2326 0, /* tp_weaklistoffset */
2327 0, /* tp_iter */
2328 0, /* tp_iternext */
2329 kqueue_queue_methods, /* tp_methods */
2330 0, /* tp_members */
2331 kqueue_queue_getsetlist, /* tp_getset */
2332 0, /* tp_base */
2333 0, /* tp_dict */
2334 0, /* tp_descr_get */
2335 0, /* tp_descr_set */
2336 0, /* tp_dictoffset */
2337 0, /* tp_init */
2338 0, /* tp_alloc */
2339 kqueue_queue_new, /* tp_new */
2340 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002341};
2342
2343#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002344
2345
2346
2347
2348
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002349/* ************************************************************************ */
2350
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002351PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002352"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2353\n\
2354Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002355The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002356rlist -- wait until ready for reading\n\
2357wlist -- wait until ready for writing\n\
2358xlist -- wait for an ``exceptional condition''\n\
2359If only one kind of condition is required, pass [] for the other lists.\n\
2360A file descriptor is either a socket or file object, or a small integer\n\
2361gotten from a fileno() method call on one of those.\n\
2362\n\
2363The optional 4th argument specifies a timeout in seconds; it may be\n\
2364a floating point number to specify fractions of seconds. If it is absent\n\
2365or None, the call will never time out.\n\
2366\n\
2367The return value is a tuple of three lists corresponding to the first three\n\
2368arguments; each contains the subset of the corresponding file descriptors\n\
2369that are ready.\n\
2370\n\
2371*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002372On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002373descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002374
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002375static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002377#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002379#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002380#ifdef HAVE_SYS_DEVPOLL_H
2381 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2382#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002384};
2385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002386PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002387"This module supports asynchronous I/O on multiple file descriptors.\n\
2388\n\
2389*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002390On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002391
Martin v. Löwis1a214512008-06-11 05:26:20 +00002392
2393static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 PyModuleDef_HEAD_INIT,
2395 "select",
2396 module_doc,
2397 -1,
2398 select_methods,
2399 NULL,
2400 NULL,
2401 NULL,
2402 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002403};
2404
Jesus Cead8b9ae62011-11-14 19:07:41 +01002405
2406
2407
Mark Hammond62b1ab12002-07-23 06:31:15 +00002408PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002409PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyObject *m;
2412 m = PyModule_Create(&selectmodule);
2413 if (m == NULL)
2414 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002415
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002416 Py_INCREF(PyExc_OSError);
2417 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002418
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002419#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002420#ifdef HAVE_BROKEN_PIPE_BUF
2421#undef PIPE_BUF
2422#define PIPE_BUF 512
2423#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002424 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002425#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002426
Charles-François Natali986a56c2013-01-19 12:19:10 +01002427#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002428#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 if (select_have_broken_poll()) {
2430 if (PyObject_DelAttrString(m, "poll") == -1) {
2431 PyErr_Clear();
2432 }
2433 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002434#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002436#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 if (PyType_Ready(&poll_Type) < 0)
2438 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002439 PyModule_AddIntMacro(m, POLLIN);
2440 PyModule_AddIntMacro(m, POLLPRI);
2441 PyModule_AddIntMacro(m, POLLOUT);
2442 PyModule_AddIntMacro(m, POLLERR);
2443 PyModule_AddIntMacro(m, POLLHUP);
2444 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002445
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002446#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002447 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002448#endif
2449#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002450 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002451#endif
2452#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002453 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002454#endif
2455#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002456 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002457#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002458#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002459 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002460#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002461#ifdef POLLRDHUP
2462 /* Kernel 2.6.17+ */
2463 PyModule_AddIntMacro(m, POLLRDHUP);
2464#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002466#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002467
Jesus Cead8b9ae62011-11-14 19:07:41 +01002468#ifdef HAVE_SYS_DEVPOLL_H
2469 if (PyType_Ready(&devpoll_Type) < 0)
2470 return NULL;
2471#endif
2472
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002473#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2475 if (PyType_Ready(&pyEpoll_Type) < 0)
2476 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 Py_INCREF(&pyEpoll_Type);
2479 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002480
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002481 PyModule_AddIntMacro(m, EPOLLIN);
2482 PyModule_AddIntMacro(m, EPOLLOUT);
2483 PyModule_AddIntMacro(m, EPOLLPRI);
2484 PyModule_AddIntMacro(m, EPOLLERR);
2485 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002486#ifdef EPOLLRDHUP
2487 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002488 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002489#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002490 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002491#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002493 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002494#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002495#ifdef EPOLLEXCLUSIVE
2496 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2497#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002498
2499#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002500 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002501#endif
2502#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002503 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002504#endif
2505#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002506 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002507#endif
2508#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002509 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002510#endif
2511#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002512 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002513#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002514
Benjamin Peterson95c16622011-12-27 15:36:32 -06002515#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002516 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002517#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002518#endif /* HAVE_EPOLL */
2519
2520#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 kqueue_event_Type.tp_new = PyType_GenericNew;
2522 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2523 if(PyType_Ready(&kqueue_event_Type) < 0)
2524 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 Py_INCREF(&kqueue_event_Type);
2527 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2530 if(PyType_Ready(&kqueue_queue_Type) < 0)
2531 return NULL;
2532 Py_INCREF(&kqueue_queue_Type);
2533 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2534
2535 /* event filters */
2536 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2537 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002538#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002540#endif
2541#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002543#endif
2544#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002545 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002546#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002547#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002549#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002550#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002552#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002553 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 /* event flags */
2556 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2557 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2558 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2559 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2560 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2561 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002562
Berker Peksag7ec64562016-09-14 18:16:59 +03002563#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002565#endif
2566#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002567 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002568#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2571 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002574#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002579#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002580 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2581 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2582 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2583 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2584 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2585 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2586 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002590#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2592 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2593 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2594 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2595 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002597 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2598 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2599 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002600#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601
2602 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002603#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2605 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2606 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002607#endif
2608
2609#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002610 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002611}