blob: d763bae4be460c4ad79b39afc25346ba98b9540c [file] [log] [blame]
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00001/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002 Under Unix, the file descriptors are small integers.
3 Under Win32, select only exists for sockets, and sockets may
4 have any value except INVALID_SOCKET.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00005*/
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Berker Peksagfe8d9662016-07-19 21:09:26 +03007#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE)
8#define _GNU_SOURCE
9#endif
10
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000011#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +000012#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +000013
Jesus Cead8b9ae62011-11-14 19:07:41 +010014#ifdef HAVE_SYS_DEVPOLL_H
15#include <sys/resource.h>
16#include <sys/devpoll.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#endif
21
Thomas Wouters477c8d52006-05-27 19:21:47 +000022#ifdef __APPLE__
23 /* Perform runtime testing for a broken poll on OSX to make it easier
24 * to use the same binary on multiple releases of the OS.
25 */
26#undef HAVE_BROKEN_POLL
27#endif
28
Tim Petersd92dfe02000-12-12 01:18:41 +000029/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
30 64 is too small (too many people have bumped into that limit).
31 Here we boost it.
32 Users who want even more than the boosted limit should #define
33 FD_SETSIZE higher before this; e.g., via compiler /D switch.
34*/
35#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
36#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000038
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000039#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000040#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000041#elif defined(HAVE_SYS_POLL_H)
42#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000043#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000044
Guido van Rossum37273171996-12-09 18:47:43 +000045#ifdef __sgi
46/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000047extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000048#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000052#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053
Guido van Rossum6f489d91996-06-28 20:15:15 +000054#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000055# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000057#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000059#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000060
Barry Warsawc1cb3601996-12-12 22:16:21 +000061/* list of Python objects and their file descriptor */
62typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 PyObject *obj; /* owned reference */
64 SOCKET fd;
65 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000066} pylist;
67
Barry Warsawc1cb3601996-12-12 22:16:21 +000068static void
Tim Peters4b046c22001-08-16 21:59:46 +000069reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000070{
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020071 unsigned int i;
72 for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +020073 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 }
75 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000076}
77
78
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000079/* returns -1 and sets the Python exception if an error occurred, otherwise
80 returns a number >= 0
81*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000082static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000083seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 int max = -1;
Serhiy Storchaka783d0c12017-03-12 14:43:12 +020086 unsigned int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010087 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 PyObject* fast_seq = NULL;
89 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
92 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000094 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 if (!fast_seq)
96 return -1;
97
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010098 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 SOCKET v;
100
101 /* any intervening fileno() calls could decr this refcnt */
102 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +0200103 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 Py_INCREF(o);
106 v = PyObject_AsFileDescriptor( o );
107 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000108
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000109#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000111#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200112 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 PyErr_SetString(PyExc_ValueError,
114 "filedescriptor out of range in select()");
115 goto finally;
116 }
117 if (v > max)
118 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 /* add object and its file descriptor to the list */
Serhiy Storchaka783d0c12017-03-12 14:43:12 +0200123 if (index >= (unsigned int)FD_SETSIZE) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 PyErr_SetString(PyExc_ValueError,
125 "too many file descriptors in select()");
126 goto finally;
127 }
128 fd2obj[index].obj = o;
129 fd2obj[index].fd = v;
130 fd2obj[index].sentinel = 0;
131 fd2obj[++index].sentinel = -1;
132 }
133 Py_DECREF(fast_seq);
134 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135
136 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 Py_XDECREF(o);
138 Py_DECREF(fast_seq);
139 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000140}
141
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000142/* returns NULL and sets the Python exception if an error occurred */
143static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 int i, j, count=0;
147 PyObject *list, *o;
148 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
151 if (FD_ISSET(fd2obj[j].fd, set))
152 count++;
153 }
154 list = PyList_New(count);
155 if (!list)
156 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 i = 0;
159 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
160 fd = fd2obj[j].fd;
161 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 o = fd2obj[j].obj;
163 fd2obj[j].obj = NULL;
164 /* transfer ownership */
165 if (PyList_SetItem(list, i, o) < 0)
166 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 i++;
169 }
170 }
171 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 Py_DECREF(list);
174 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000175}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000176
Barry Warsawb44740f2001-08-16 16:52:59 +0000177#undef SELECT_USES_HEAP
178#if FD_SETSIZE > 1024
179#define SELECT_USES_HEAP
180#endif /* FD_SETSIZE > 1024 */
181
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000182static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000183select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000184{
Barry Warsawb44740f2001-08-16 16:52:59 +0000185#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000187#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 /* XXX: All this should probably be implemented as follows:
189 * - find the highest descriptor we're interested in
190 * - add one
191 * - that's the size
192 * See: Stevens, APitUE, $12.5.1
193 */
194 pylist rfd2obj[FD_SETSIZE + 1];
195 pylist wfd2obj[FD_SETSIZE + 1];
196 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000197#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 PyObject *ifdlist, *ofdlist, *efdlist;
199 PyObject *ret = NULL;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200200 PyObject *timeout_obj = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 int imax, omax, emax, max;
204 int n;
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200205 _PyTime_t timeout, deadline = 0;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 /* convert arguments */
208 if (!PyArg_UnpackTuple(args, "select", 3, 4,
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200209 &ifdlist, &ofdlist, &efdlist, &timeout_obj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000211
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200212 if (timeout_obj == Py_None)
213 tvp = (struct timeval *)NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 else {
Victor Stinnerf70e1ca2015-03-30 21:16:11 +0200215 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
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
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200434 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000435}
436
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000437PyDoc_STRVAR(poll_modify_doc,
438"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000439Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000440fd -- either an integer, or an object with a fileno() method returning an\n\
441 int.\n\
442events -- an optional bitmask describing the type of events to check for");
443
444static PyObject *
445poll_modify(pollObject *self, PyObject *args)
446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200448 int fd;
449 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000451
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200452 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 fd = PyObject_AsFileDescriptor(o);
456 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 /* Modify registered fd */
459 key = PyLong_FromLong(fd);
460 if (key == NULL)
461 return NULL;
462 if (PyDict_GetItem(self->dict, key) == NULL) {
463 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200464 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200465 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return NULL;
467 }
468 value = PyLong_FromLong(events);
469 if (value == NULL) {
470 Py_DECREF(key);
471 return NULL;
472 }
473 err = PyDict_SetItem(self->dict, key, value);
474 Py_DECREF(key);
475 Py_DECREF(value);
476 if (err < 0)
477 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 self->ufd_uptodate = 0;
480
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200481 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000482}
483
484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000485PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000486"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000487Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000488
489static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 PyObject *key;
493 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 fd = PyObject_AsFileDescriptor( o );
496 if (fd == -1)
497 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 /* Check whether the fd is already in the array */
500 key = PyLong_FromLong(fd);
501 if (key == NULL)
502 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (PyDict_DelItem(self->dict, key) == -1) {
505 Py_DECREF(key);
506 /* This will simply raise the KeyError set by PyDict_DelItem
507 if the file descriptor isn't registered. */
508 return NULL;
509 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 Py_DECREF(key);
512 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000513
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200514 Py_RETURN_NONE;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515}
516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000517PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
519Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000520any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000521
522static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000524{
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200525 PyObject *result_list = NULL, *timeout_obj = NULL;
526 int poll_result, i, j;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PyObject *value = NULL, *num = NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200528 _PyTime_t timeout, ms, deadline;
529 int async_err = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000530
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200531 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 return NULL;
533 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 /* Check values for timeout */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200536 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 timeout = -1;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200538 ms = -1;
Victor Stinner41eba222015-03-30 21:59:21 +0200539 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 }
541 else {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200542 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
543 _PyTime_ROUND_CEILING) < 0) {
544 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
545 PyErr_SetString(PyExc_TypeError,
546 "timeout must be an integer or None");
547 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200549 }
550
551 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
552 if (ms < INT_MIN || ms > INT_MAX) {
553 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 return NULL;
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200555 }
556
557 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000559
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300560 /* Avoid concurrent poll() invocation, issue 8865 */
561 if (self->poll_running) {
562 PyErr_SetString(PyExc_RuntimeError,
563 "concurrent poll() invocation");
564 return NULL;
565 }
566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 /* Ensure the ufd array is up to date */
568 if (!self->ufd_uptodate)
569 if (update_ufd_array(self) == 0)
570 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000571
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300572 self->poll_running = 1;
573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 /* call poll() */
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200575 async_err = 0;
576 do {
577 Py_BEGIN_ALLOW_THREADS
578 errno = 0;
579 poll_result = poll(self->ufds, self->ufd_len, (int)ms);
580 Py_END_ALLOW_THREADS
581
582 if (errno != EINTR)
583 break;
584
585 /* poll() was interrupted by a signal */
586 if (PyErr_CheckSignals()) {
587 async_err = 1;
588 break;
589 }
590
591 if (timeout >= 0) {
592 timeout = deadline - _PyTime_GetMonotonicClock();
593 if (timeout < 0) {
594 poll_result = 0;
595 break;
596 }
597 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
598 /* retry poll() with the recomputed timeout */
599 }
600 } while (1);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000601
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300602 self->poll_running = 0;
603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 if (poll_result < 0) {
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200605 if (!async_err)
606 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 return NULL;
608 }
609
610 /* build the result list */
611
612 result_list = PyList_New(poll_result);
613 if (!result_list)
614 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200616 for (i = 0, j = 0; j < poll_result; j++) {
617 /* skip to the next fired descriptor */
618 while (!self->ufds[i].revents) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 i++;
620 }
Victor Stinner3c7d6e02015-03-30 21:38:00 +0200621 /* if we hit a NULL return, set value to NULL
622 and break out of loop; code at end will
623 clean up result_list */
624 value = PyTuple_New(2);
625 if (value == NULL)
626 goto error;
627 num = PyLong_FromLong(self->ufds[i].fd);
628 if (num == NULL) {
629 Py_DECREF(value);
630 goto error;
631 }
632 PyTuple_SET_ITEM(value, 0, num);
633
634 /* The &0xffff is a workaround for AIX. 'revents'
635 is a 16-bit short, and IBM assigned POLLNVAL
636 to be 0x8000, so the conversion to int results
637 in a negative number. See SF bug #923315. */
638 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
639 if (num == NULL) {
640 Py_DECREF(value);
641 goto error;
642 }
643 PyTuple_SET_ITEM(value, 1, num);
644 if ((PyList_SetItem(result_list, j, value)) == -1) {
645 Py_DECREF(value);
646 goto error;
647 }
648 i++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 }
650 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000651
652 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 Py_DECREF(result_list);
654 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655}
656
657static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 {"register", (PyCFunction)poll_register,
659 METH_VARARGS, poll_register_doc},
660 {"modify", (PyCFunction)poll_modify,
661 METH_VARARGS, poll_modify_doc},
662 {"unregister", (PyCFunction)poll_unregister,
663 METH_O, poll_unregister_doc},
664 {"poll", (PyCFunction)poll_poll,
665 METH_VARARGS, poll_poll_doc},
666 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000667};
668
669static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000670newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 pollObject *self;
673 self = PyObject_New(pollObject, &poll_Type);
674 if (self == NULL)
675 return NULL;
676 /* ufd_uptodate is a Boolean, denoting whether the
677 array pointed to by ufds matches the contents of the dictionary. */
678 self->ufd_uptodate = 0;
679 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300680 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 self->dict = PyDict_New();
682 if (self->dict == NULL) {
683 Py_DECREF(self);
684 return NULL;
685 }
686 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000687}
688
689static void
690poll_dealloc(pollObject *self)
691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 if (self->ufds != NULL)
693 PyMem_DEL(self->ufds);
694 Py_XDECREF(self->dict);
695 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000696}
697
Tim Peters0c322792002-07-17 16:49:03 +0000698static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 /* The ob_type field must be initialized in the module init function
700 * to be portable to Windows without using C++. */
701 PyVarObject_HEAD_INIT(NULL, 0)
702 "select.poll", /*tp_name*/
703 sizeof(pollObject), /*tp_basicsize*/
704 0, /*tp_itemsize*/
705 /* methods */
706 (destructor)poll_dealloc, /*tp_dealloc*/
707 0, /*tp_print*/
708 0, /*tp_getattr*/
709 0, /*tp_setattr*/
710 0, /*tp_reserved*/
711 0, /*tp_repr*/
712 0, /*tp_as_number*/
713 0, /*tp_as_sequence*/
714 0, /*tp_as_mapping*/
715 0, /*tp_hash*/
716 0, /*tp_call*/
717 0, /*tp_str*/
718 0, /*tp_getattro*/
719 0, /*tp_setattro*/
720 0, /*tp_as_buffer*/
721 Py_TPFLAGS_DEFAULT, /*tp_flags*/
722 0, /*tp_doc*/
723 0, /*tp_traverse*/
724 0, /*tp_clear*/
725 0, /*tp_richcompare*/
726 0, /*tp_weaklistoffset*/
727 0, /*tp_iter*/
728 0, /*tp_iternext*/
729 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000730};
731
Jesus Cead8b9ae62011-11-14 19:07:41 +0100732#ifdef HAVE_SYS_DEVPOLL_H
733typedef struct {
734 PyObject_HEAD
735 int fd_devpoll;
736 int max_n_fds;
737 int n_fds;
738 struct pollfd *fds;
739} devpollObject;
740
741static PyTypeObject devpoll_Type;
742
Victor Stinner13423c32013-08-22 00:19:50 +0200743static PyObject *
744devpoll_err_closed(void)
745{
746 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
747 return NULL;
748}
749
Jesus Cead8b9ae62011-11-14 19:07:41 +0100750static int devpoll_flush(devpollObject *self)
751{
752 int size, n;
753
754 if (!self->n_fds) return 0;
755
756 size = sizeof(struct pollfd)*self->n_fds;
757 self->n_fds = 0;
758
Victor Stinner54799672015-03-19 23:33:09 +0100759 n = _Py_write(self->fd_devpoll, self->fds, size);
760 if (n == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +0100761 return -1;
Victor Stinner54799672015-03-19 23:33:09 +0100762
Jesus Cead8b9ae62011-11-14 19:07:41 +0100763 if (n < size) {
764 /*
765 ** Data writed to /dev/poll is a binary data structure. It is not
766 ** clear what to do if a partial write occurred. For now, raise
767 ** an exception and see if we actually found this problem in
768 ** the wild.
769 ** See http://bugs.python.org/issue6397.
770 */
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300771 PyErr_Format(PyExc_OSError, "failed to write all pollfds. "
Jesus Cead8b9ae62011-11-14 19:07:41 +0100772 "Please, report at http://bugs.python.org/. "
773 "Data to report: Size tried: %d, actual size written: %d.",
774 size, n);
775 return -1;
776 }
777 return 0;
778}
779
780static PyObject *
781internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
782{
783 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200784 int fd;
785 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100786
Victor Stinner13423c32013-08-22 00:19:50 +0200787 if (self->fd_devpoll < 0)
788 return devpoll_err_closed();
789
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200790 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100791 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100792
793 fd = PyObject_AsFileDescriptor(o);
794 if (fd == -1) return NULL;
795
796 if (remove) {
797 self->fds[self->n_fds].fd = fd;
798 self->fds[self->n_fds].events = POLLREMOVE;
799
800 if (++self->n_fds == self->max_n_fds) {
801 if (devpoll_flush(self))
802 return NULL;
803 }
804 }
805
806 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200807 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100808
809 if (++self->n_fds == self->max_n_fds) {
810 if (devpoll_flush(self))
811 return NULL;
812 }
813
814 Py_RETURN_NONE;
815}
816
817PyDoc_STRVAR(devpoll_register_doc,
818"register(fd [, eventmask] ) -> None\n\n\
819Register a file descriptor with the polling object.\n\
820fd -- either an integer, or an object with a fileno() method returning an\n\
821 int.\n\
822events -- an optional bitmask describing the type of events to check for");
823
824static PyObject *
825devpoll_register(devpollObject *self, PyObject *args)
826{
827 return internal_devpoll_register(self, args, 0);
828}
829
830PyDoc_STRVAR(devpoll_modify_doc,
831"modify(fd[, eventmask]) -> None\n\n\
832Modify a possible already registered file descriptor.\n\
833fd -- either an integer, or an object with a fileno() method returning an\n\
834 int.\n\
835events -- an optional bitmask describing the type of events to check for");
836
837static PyObject *
838devpoll_modify(devpollObject *self, PyObject *args)
839{
840 return internal_devpoll_register(self, args, 1);
841}
842
843
844PyDoc_STRVAR(devpoll_unregister_doc,
845"unregister(fd) -> None\n\n\
846Remove a file descriptor being tracked by the polling object.");
847
848static PyObject *
849devpoll_unregister(devpollObject *self, PyObject *o)
850{
851 int fd;
852
Victor Stinner13423c32013-08-22 00:19:50 +0200853 if (self->fd_devpoll < 0)
854 return devpoll_err_closed();
855
Jesus Cead8b9ae62011-11-14 19:07:41 +0100856 fd = PyObject_AsFileDescriptor( o );
857 if (fd == -1)
858 return NULL;
859
860 self->fds[self->n_fds].fd = fd;
861 self->fds[self->n_fds].events = POLLREMOVE;
862
863 if (++self->n_fds == self->max_n_fds) {
864 if (devpoll_flush(self))
865 return NULL;
866 }
867
868 Py_RETURN_NONE;
869}
870
871PyDoc_STRVAR(devpoll_poll_doc,
872"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
873Polls the set of registered file descriptors, returning a list containing \n\
874any descriptors that have events or errors to report.");
875
876static PyObject *
877devpoll_poll(devpollObject *self, PyObject *args)
878{
879 struct dvpoll dvp;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200880 PyObject *result_list = NULL, *timeout_obj = NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100881 int poll_result, i;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100882 PyObject *value, *num1, *num2;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200883 _PyTime_t timeout, ms, deadline = 0;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100884
Victor Stinner13423c32013-08-22 00:19:50 +0200885 if (self->fd_devpoll < 0)
886 return devpoll_err_closed();
887
Victor Stinner45ca48b2015-03-31 12:10:33 +0200888 if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100889 return NULL;
890 }
891
892 /* Check values for timeout */
Victor Stinner45ca48b2015-03-31 12:10:33 +0200893 if (timeout_obj == NULL || timeout_obj == Py_None) {
Jesus Cead8b9ae62011-11-14 19:07:41 +0100894 timeout = -1;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200895 ms = -1;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100896 }
897 else {
Victor Stinner45ca48b2015-03-31 12:10:33 +0200898 if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
899 _PyTime_ROUND_CEILING) < 0) {
900 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
901 PyErr_SetString(PyExc_TypeError,
902 "timeout must be an integer or None");
903 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100904 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200905 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100906
Victor Stinner45ca48b2015-03-31 12:10:33 +0200907 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
908 if (ms < -1 || ms > INT_MAX) {
909 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
910 return NULL;
911 }
Jesus Cead8b9ae62011-11-14 19:07:41 +0100912 }
913
914 if (devpoll_flush(self))
915 return NULL;
916
917 dvp.dp_fds = self->fds;
918 dvp.dp_nfds = self->max_n_fds;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200919 dvp.dp_timeout = (int)ms;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100920
Victor Stinner45ca48b2015-03-31 12:10:33 +0200921 if (timeout >= 0)
922 deadline = _PyTime_GetMonotonicClock() + timeout;
923
924 do {
925 /* call devpoll() */
926 Py_BEGIN_ALLOW_THREADS
927 errno = 0;
928 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
929 Py_END_ALLOW_THREADS
930
931 if (errno != EINTR)
932 break;
933
934 /* devpoll() was interrupted by a signal */
935 if (PyErr_CheckSignals())
936 return NULL;
937
938 if (timeout >= 0) {
939 timeout = deadline - _PyTime_GetMonotonicClock();
940 if (timeout < 0) {
941 poll_result = 0;
942 break;
943 }
944 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
945 dvp.dp_timeout = (int)ms;
946 /* retry devpoll() with the recomputed timeout */
947 }
948 } while (1);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100949
950 if (poll_result < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300951 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cead8b9ae62011-11-14 19:07:41 +0100952 return NULL;
953 }
954
955 /* build the result list */
Jesus Cead8b9ae62011-11-14 19:07:41 +0100956 result_list = PyList_New(poll_result);
957 if (!result_list)
958 return NULL;
Victor Stinner45ca48b2015-03-31 12:10:33 +0200959
960 for (i = 0; i < poll_result; i++) {
961 num1 = PyLong_FromLong(self->fds[i].fd);
962 num2 = PyLong_FromLong(self->fds[i].revents);
963 if ((num1 == NULL) || (num2 == NULL)) {
964 Py_XDECREF(num1);
965 Py_XDECREF(num2);
966 goto error;
967 }
968 value = PyTuple_Pack(2, num1, num2);
969 Py_DECREF(num1);
970 Py_DECREF(num2);
971 if (value == NULL)
972 goto error;
973 if ((PyList_SetItem(result_list, i, value)) == -1) {
974 Py_DECREF(value);
975 goto error;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100976 }
977 }
978
979 return result_list;
980
981 error:
982 Py_DECREF(result_list);
983 return NULL;
984}
985
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100986static int
987devpoll_internal_close(devpollObject *self)
988{
989 int save_errno = 0;
990 if (self->fd_devpoll >= 0) {
991 int fd = self->fd_devpoll;
992 self->fd_devpoll = -1;
993 Py_BEGIN_ALLOW_THREADS
994 if (close(fd) < 0)
995 save_errno = errno;
996 Py_END_ALLOW_THREADS
997 }
998 return save_errno;
999}
1000
Victor Stinner13423c32013-08-22 00:19:50 +02001001static PyObject*
1002devpoll_close(devpollObject *self)
1003{
1004 errno = devpoll_internal_close(self);
1005 if (errno < 0) {
1006 PyErr_SetFromErrno(PyExc_OSError);
1007 return NULL;
1008 }
1009 Py_RETURN_NONE;
1010}
1011
1012PyDoc_STRVAR(devpoll_close_doc,
1013"close() -> None\n\
1014\n\
1015Close the devpoll file descriptor. Further operations on the devpoll\n\
1016object will raise an exception.");
1017
1018static PyObject*
1019devpoll_get_closed(devpollObject *self)
1020{
1021 if (self->fd_devpoll < 0)
1022 Py_RETURN_TRUE;
1023 else
1024 Py_RETURN_FALSE;
1025}
1026
1027static PyObject*
1028devpoll_fileno(devpollObject *self)
1029{
1030 if (self->fd_devpoll < 0)
1031 return devpoll_err_closed();
1032 return PyLong_FromLong(self->fd_devpoll);
1033}
1034
1035PyDoc_STRVAR(devpoll_fileno_doc,
1036"fileno() -> int\n\
1037\n\
1038Return the file descriptor.");
1039
Jesus Cead8b9ae62011-11-14 19:07:41 +01001040static PyMethodDef devpoll_methods[] = {
1041 {"register", (PyCFunction)devpoll_register,
1042 METH_VARARGS, devpoll_register_doc},
1043 {"modify", (PyCFunction)devpoll_modify,
1044 METH_VARARGS, devpoll_modify_doc},
1045 {"unregister", (PyCFunction)devpoll_unregister,
1046 METH_O, devpoll_unregister_doc},
1047 {"poll", (PyCFunction)devpoll_poll,
1048 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +02001049 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
1050 devpoll_close_doc},
1051 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
1052 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +01001053 {NULL, NULL} /* sentinel */
1054};
1055
Victor Stinner13423c32013-08-22 00:19:50 +02001056static PyGetSetDef devpoll_getsetlist[] = {
1057 {"closed", (getter)devpoll_get_closed, NULL,
1058 "True if the devpoll object is closed"},
1059 {0},
1060};
1061
Jesus Cead8b9ae62011-11-14 19:07:41 +01001062static devpollObject *
1063newDevPollObject(void)
1064{
1065 devpollObject *self;
1066 int fd_devpoll, limit_result;
1067 struct pollfd *fds;
1068 struct rlimit limit;
1069
Jesus Cead8b9ae62011-11-14 19:07:41 +01001070 /*
1071 ** If we try to process more that getrlimit()
1072 ** fds, the kernel will give an error, so
1073 ** we set the limit here. It is a dynamic
1074 ** value, because we can change rlimit() anytime.
1075 */
1076 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001077 if (limit_result == -1) {
1078 PyErr_SetFromErrno(PyExc_OSError);
1079 return NULL;
1080 }
Victor Stinnera555cfc2015-03-18 00:22:14 +01001081
1082 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
1083 if (fd_devpoll == -1)
Jesus Cead8b9ae62011-11-14 19:07:41 +01001084 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +01001085
1086 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1087 if (fds == NULL) {
1088 close(fd_devpoll);
1089 PyErr_NoMemory();
1090 return NULL;
1091 }
1092
1093 self = PyObject_New(devpollObject, &devpoll_Type);
1094 if (self == NULL) {
1095 close(fd_devpoll);
1096 PyMem_DEL(fds);
1097 return NULL;
1098 }
1099 self->fd_devpoll = fd_devpoll;
1100 self->max_n_fds = limit.rlim_cur;
1101 self->n_fds = 0;
1102 self->fds = fds;
1103
1104 return self;
1105}
1106
1107static void
1108devpoll_dealloc(devpollObject *self)
1109{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001110 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001111 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001112 PyObject_Del(self);
1113}
1114
1115static PyTypeObject devpoll_Type = {
1116 /* The ob_type field must be initialized in the module init function
1117 * to be portable to Windows without using C++. */
1118 PyVarObject_HEAD_INIT(NULL, 0)
1119 "select.devpoll", /*tp_name*/
1120 sizeof(devpollObject), /*tp_basicsize*/
1121 0, /*tp_itemsize*/
1122 /* methods */
1123 (destructor)devpoll_dealloc, /*tp_dealloc*/
1124 0, /*tp_print*/
1125 0, /*tp_getattr*/
1126 0, /*tp_setattr*/
1127 0, /*tp_reserved*/
1128 0, /*tp_repr*/
1129 0, /*tp_as_number*/
1130 0, /*tp_as_sequence*/
1131 0, /*tp_as_mapping*/
1132 0, /*tp_hash*/
1133 0, /*tp_call*/
1134 0, /*tp_str*/
1135 0, /*tp_getattro*/
1136 0, /*tp_setattro*/
1137 0, /*tp_as_buffer*/
1138 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1139 0, /*tp_doc*/
1140 0, /*tp_traverse*/
1141 0, /*tp_clear*/
1142 0, /*tp_richcompare*/
1143 0, /*tp_weaklistoffset*/
1144 0, /*tp_iter*/
1145 0, /*tp_iternext*/
1146 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001147 0, /* tp_members */
1148 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001149};
1150#endif /* HAVE_SYS_DEVPOLL_H */
1151
1152
1153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001154PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001155"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001156unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001157
1158static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001159select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001162}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001163
Jesus Cead8b9ae62011-11-14 19:07:41 +01001164#ifdef HAVE_SYS_DEVPOLL_H
1165PyDoc_STRVAR(devpoll_doc,
1166"Returns a polling object, which supports registering and\n\
1167unregistering file descriptors, and then polling them for I/O events.");
1168
1169static PyObject *
1170select_devpoll(PyObject *self, PyObject *unused)
1171{
1172 return (PyObject *)newDevPollObject();
1173}
1174#endif
1175
1176
Thomas Wouters477c8d52006-05-27 19:21:47 +00001177#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001179 * On some systems poll() sets errno on invalid file descriptors. We test
1180 * for this at runtime because this bug may be fixed or introduced between
1181 * OS releases.
1182 */
1183static int select_have_broken_poll(void)
1184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 int poll_test;
1186 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 /* Create a file descriptor to make invalid */
1191 if (pipe(filedes) < 0) {
1192 return 1;
1193 }
1194 poll_struct.fd = filedes[0];
1195 close(filedes[0]);
1196 close(filedes[1]);
1197 poll_test = poll(&poll_struct, 1, 0);
1198 if (poll_test < 0) {
1199 return 1;
1200 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1201 return 1;
1202 }
1203 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204}
1205#endif /* __APPLE__ */
1206
1207#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001208
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001209#ifdef HAVE_EPOLL
1210/* **************************************************************************
1211 * epoll interface for Linux 2.6
1212 *
1213 * Written by Christian Heimes
1214 * Inspired by Twisted's _epoll.pyx and select.poll()
1215 */
1216
1217#ifdef HAVE_SYS_EPOLL_H
1218#include <sys/epoll.h>
1219#endif
1220
1221typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001223 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001224} pyEpoll_Object;
1225
1226static PyTypeObject pyEpoll_Type;
1227#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1228
1229static PyObject *
1230pyepoll_err_closed(void)
1231{
Victor Stinner13423c32013-08-22 00:19:50 +02001232 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001234}
1235
1236static int
1237pyepoll_internal_close(pyEpoll_Object *self)
1238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 int save_errno = 0;
1240 if (self->epfd >= 0) {
1241 int epfd = self->epfd;
1242 self->epfd = -1;
1243 Py_BEGIN_ALLOW_THREADS
1244 if (close(epfd) < 0)
1245 save_errno = errno;
1246 Py_END_ALLOW_THREADS
1247 }
1248 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001249}
1250
1251static PyObject *
Berker Peksage2197d12016-09-26 23:30:41 +03001252newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 assert(type != NULL && type->tp_alloc != NULL);
1257 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1258 if (self == NULL)
1259 return NULL;
1260
1261 if (fd == -1) {
1262 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001263#ifdef HAVE_EPOLL_CREATE1
Berker Peksage2197d12016-09-26 23:30:41 +03001264 self->epfd = epoll_create1(EPOLL_CLOEXEC);
1265#else
Benjamin Peterson83251c12011-12-27 16:01:21 -06001266 self->epfd = epoll_create(sizehint);
Berker Peksage2197d12016-09-26 23:30:41 +03001267#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 Py_END_ALLOW_THREADS
1269 }
1270 else {
1271 self->epfd = fd;
1272 }
1273 if (self->epfd < 0) {
1274 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001275 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 return NULL;
1277 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001278
1279#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001280 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001281 Py_DECREF(self);
1282 return NULL;
1283 }
1284#endif
1285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001287}
1288
1289
1290static PyObject *
1291pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1292{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001293 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001294 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001295
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001296 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1297 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001299 if (sizehint < 0) {
1300 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1301 return NULL;
1302 }
Berker Peksage2197d12016-09-26 23:30:41 +03001303 if (flags && flags != EPOLL_CLOEXEC) {
1304 PyErr_SetString(PyExc_OSError, "invalid flags");
1305 return NULL;
1306 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001307
Berker Peksage2197d12016-09-26 23:30:41 +03001308 return newPyEpoll_Object(type, sizehint, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001309}
1310
1311
1312static void
1313pyepoll_dealloc(pyEpoll_Object *self)
1314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 (void)pyepoll_internal_close(self);
1316 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001317}
1318
1319static PyObject*
1320pyepoll_close(pyEpoll_Object *self)
1321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 errno = pyepoll_internal_close(self);
1323 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001324 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 return NULL;
1326 }
1327 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001328}
1329
1330PyDoc_STRVAR(pyepoll_close_doc,
1331"close() -> None\n\
1332\n\
1333Close the epoll control file descriptor. Further operations on the epoll\n\
1334object will raise an exception.");
1335
1336static PyObject*
1337pyepoll_get_closed(pyEpoll_Object *self)
1338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 if (self->epfd < 0)
1340 Py_RETURN_TRUE;
1341 else
1342 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001343}
1344
1345static PyObject*
1346pyepoll_fileno(pyEpoll_Object *self)
1347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if (self->epfd < 0)
1349 return pyepoll_err_closed();
1350 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001351}
1352
1353PyDoc_STRVAR(pyepoll_fileno_doc,
1354"fileno() -> int\n\
1355\n\
1356Return the epoll control file descriptor.");
1357
1358static PyObject*
1359pyepoll_fromfd(PyObject *cls, PyObject *args)
1360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1364 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001365
Berker Peksage2197d12016-09-26 23:30:41 +03001366 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001367}
1368
1369PyDoc_STRVAR(pyepoll_fromfd_doc,
1370"fromfd(fd) -> epoll\n\
1371\n\
1372Create an epoll object from a given control fd.");
1373
1374static PyObject *
1375pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 struct epoll_event ev;
1378 int result;
1379 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 if (epfd < 0)
1382 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 fd = PyObject_AsFileDescriptor(pfd);
1385 if (fd == -1) {
1386 return NULL;
1387 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001388
Guido van Rossumee07b942013-12-06 17:46:22 -08001389 switch (op) {
1390 case EPOLL_CTL_ADD:
1391 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 ev.events = events;
1393 ev.data.fd = fd;
1394 Py_BEGIN_ALLOW_THREADS
1395 result = epoll_ctl(epfd, op, fd, &ev);
1396 Py_END_ALLOW_THREADS
1397 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001398 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1400 * operation required a non-NULL pointer in event, even
1401 * though this argument is ignored. */
1402 Py_BEGIN_ALLOW_THREADS
1403 result = epoll_ctl(epfd, op, fd, &ev);
1404 if (errno == EBADF) {
1405 /* fd already closed */
1406 result = 0;
1407 errno = 0;
1408 }
1409 Py_END_ALLOW_THREADS
1410 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001411 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 result = -1;
1413 errno = EINVAL;
1414 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001417 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 return NULL;
1419 }
1420 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001421}
1422
1423static PyObject *
1424pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyObject *pfd;
1427 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1428 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1431 &pfd, &events)) {
1432 return NULL;
1433 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001436}
1437
1438PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001439"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001440\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001441Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001442fd is the target file descriptor of the operation.\n\
1443events is a bit set composed of the various EPOLL constants; the default\n\
Senthil Kumaran507898d2016-05-14 21:28:22 -07001444is EPOLLIN | EPOLLOUT | EPOLLPRI.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001445\n\
1446The epoll interface supports all file descriptors that support poll.");
1447
1448static PyObject *
1449pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 PyObject *pfd;
1452 unsigned int events;
1453 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1456 &pfd, &events)) {
1457 return NULL;
1458 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001461}
1462
1463PyDoc_STRVAR(pyepoll_modify_doc,
1464"modify(fd, eventmask) -> None\n\
1465\n\
1466fd is the target file descriptor of the operation\n\
1467events is a bit set composed of the various EPOLL constants");
1468
1469static PyObject *
1470pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 PyObject *pfd;
1473 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1476 &pfd)) {
1477 return NULL;
1478 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001481}
1482
1483PyDoc_STRVAR(pyepoll_unregister_doc,
1484"unregister(fd) -> None\n\
1485\n\
1486fd is the target file descriptor of the operation.");
1487
1488static PyObject *
1489pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1490{
Victor Stinner41eba222015-03-30 21:59:21 +02001491 static char *kwlist[] = {"timeout", "maxevents", NULL};
1492 PyObject *timeout_obj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 int maxevents = -1;
1494 int nfds, i;
1495 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001496 struct epoll_event *evs = NULL;
Victor Stinner41eba222015-03-30 21:59:21 +02001497 _PyTime_t timeout, ms, deadline;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 if (self->epfd < 0)
1500 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001501
Victor Stinner41eba222015-03-30 21:59:21 +02001502 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist,
1503 &timeout_obj, &maxevents)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 return NULL;
1505 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001506
Victor Stinner41eba222015-03-30 21:59:21 +02001507 if (timeout_obj == NULL || timeout_obj == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 timeout = -1;
Victor Stinner41eba222015-03-30 21:59:21 +02001509 ms = -1;
1510 deadline = 0; /* initialize to prevent gcc warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 }
1512 else {
Victor Stinner41eba222015-03-30 21:59:21 +02001513 /* epoll_wait() has a resolution of 1 millisecond, round towards
1514 infinity to wait at least timeout seconds. */
1515 if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
1516 _PyTime_ROUND_CEILING) < 0) {
1517 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1518 PyErr_SetString(PyExc_TypeError,
1519 "timeout must be an integer or None");
1520 }
1521 return NULL;
1522 }
1523
1524 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1525 if (ms < INT_MIN || ms > INT_MAX) {
1526 PyErr_SetString(PyExc_OverflowError, "timeout is too large");
1527 return NULL;
1528 }
1529
1530 deadline = _PyTime_GetMonotonicClock() + timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001534 maxevents = FD_SETSIZE-1;
1535 }
1536 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 PyErr_Format(PyExc_ValueError,
1538 "maxevents must be greater than 0, got %d",
1539 maxevents);
1540 return NULL;
1541 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001542
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001543 evs = PyMem_New(struct epoll_event, maxevents);
1544 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001545 PyErr_NoMemory();
1546 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001548
Victor Stinner41eba222015-03-30 21:59:21 +02001549 do {
1550 Py_BEGIN_ALLOW_THREADS
1551 errno = 0;
1552 nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms);
1553 Py_END_ALLOW_THREADS
1554
1555 if (errno != EINTR)
1556 break;
1557
1558 /* poll() was interrupted by a signal */
1559 if (PyErr_CheckSignals())
1560 goto error;
1561
1562 if (timeout >= 0) {
1563 timeout = deadline - _PyTime_GetMonotonicClock();
1564 if (timeout < 0) {
1565 nfds = 0;
1566 break;
1567 }
1568 ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
1569 /* retry epoll_wait() with the recomputed timeout */
1570 }
1571 } while(1);
1572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001574 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 goto error;
1576 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 elist = PyList_New(nfds);
1579 if (elist == NULL) {
1580 goto error;
1581 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001584 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 if (etuple == NULL) {
1586 Py_CLEAR(elist);
1587 goto error;
1588 }
1589 PyList_SET_ITEM(elist, i, etuple);
1590 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001591
Christian Heimesf6cd9672008-03-26 13:45:42 +00001592 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001593 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001595}
1596
1597PyDoc_STRVAR(pyepoll_poll_doc,
1598"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1599\n\
1600Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1601in seconds (as float). -1 makes poll wait indefinitely.\n\
1602Up to maxevents are returned to the caller.");
1603
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001604static PyObject *
1605pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1606{
1607 if (self->epfd < 0)
1608 return pyepoll_err_closed();
1609
1610 Py_INCREF(self);
1611 return (PyObject *)self;
1612}
1613
1614static PyObject *
1615pyepoll_exit(PyObject *self, PyObject *args)
1616{
1617 _Py_IDENTIFIER(close);
1618
1619 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1620}
1621
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001622static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 {"fromfd", (PyCFunction)pyepoll_fromfd,
1624 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1625 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1626 pyepoll_close_doc},
1627 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1628 pyepoll_fileno_doc},
1629 {"modify", (PyCFunction)pyepoll_modify,
1630 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1631 {"register", (PyCFunction)pyepoll_register,
1632 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1633 {"unregister", (PyCFunction)pyepoll_unregister,
1634 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1635 {"poll", (PyCFunction)pyepoll_poll,
1636 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001637 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1638 NULL},
1639 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1640 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001642};
1643
1644static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 {"closed", (getter)pyepoll_get_closed, NULL,
1646 "True if the epoll handler is closed"},
1647 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001648};
1649
1650PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001651"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001652\n\
1653Returns an epolling object\n\
1654\n\
1655sizehint must be a positive integer or -1 for the default size. The\n\
1656sizehint is used to optimize internal data structures. It doesn't limit\n\
1657the maximum number of monitored events.");
1658
1659static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 PyVarObject_HEAD_INIT(NULL, 0)
1661 "select.epoll", /* tp_name */
1662 sizeof(pyEpoll_Object), /* tp_basicsize */
1663 0, /* tp_itemsize */
1664 (destructor)pyepoll_dealloc, /* tp_dealloc */
1665 0, /* tp_print */
1666 0, /* tp_getattr */
1667 0, /* tp_setattr */
1668 0, /* tp_reserved */
1669 0, /* tp_repr */
1670 0, /* tp_as_number */
1671 0, /* tp_as_sequence */
1672 0, /* tp_as_mapping */
1673 0, /* tp_hash */
1674 0, /* tp_call */
1675 0, /* tp_str */
1676 PyObject_GenericGetAttr, /* tp_getattro */
1677 0, /* tp_setattro */
1678 0, /* tp_as_buffer */
1679 Py_TPFLAGS_DEFAULT, /* tp_flags */
1680 pyepoll_doc, /* tp_doc */
1681 0, /* tp_traverse */
1682 0, /* tp_clear */
1683 0, /* tp_richcompare */
1684 0, /* tp_weaklistoffset */
1685 0, /* tp_iter */
1686 0, /* tp_iternext */
1687 pyepoll_methods, /* tp_methods */
1688 0, /* tp_members */
1689 pyepoll_getsetlist, /* tp_getset */
1690 0, /* tp_base */
1691 0, /* tp_dict */
1692 0, /* tp_descr_get */
1693 0, /* tp_descr_set */
1694 0, /* tp_dictoffset */
1695 0, /* tp_init */
1696 0, /* tp_alloc */
1697 pyepoll_new, /* tp_new */
1698 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001699};
1700
1701#endif /* HAVE_EPOLL */
1702
1703#ifdef HAVE_KQUEUE
1704/* **************************************************************************
1705 * kqueue interface for BSD
1706 *
1707 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1708 * All rights reserved.
1709 *
1710 * Redistribution and use in source and binary forms, with or without
1711 * modification, are permitted provided that the following conditions
1712 * are met:
1713 * 1. Redistributions of source code must retain the above copyright
1714 * notice, this list of conditions and the following disclaimer.
1715 * 2. Redistributions in binary form must reproduce the above copyright
1716 * notice, this list of conditions and the following disclaimer in the
1717 * documentation and/or other materials provided with the distribution.
1718 *
1719 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1720 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1721 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1722 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1723 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1724 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1725 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1726 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1727 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1728 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1729 * SUCH DAMAGE.
1730 */
1731
1732#ifdef HAVE_SYS_EVENT_H
1733#include <sys/event.h>
1734#endif
1735
1736PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001737"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001738\n\
1739This object is the equivalent of the struct kevent for the C API.\n\
1740\n\
1741See the kqueue manpage for more detailed information about the meaning\n\
1742of the arguments.\n\
1743\n\
1744One minor note: while you might hope that udata could store a\n\
1745reference to a python object, it cannot, because it is impossible to\n\
1746keep a proper reference count of the object once it's passed into the\n\
1747kernel. Therefore, I have restricted it to only storing an integer. I\n\
1748recommend ignoring it and simply using the 'ident' field to key off\n\
1749of. You could also set up a dictionary on the python side to store a\n\
1750udata->object mapping.");
1751
1752typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 PyObject_HEAD
1754 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001755} kqueue_event_Object;
1756
1757static PyTypeObject kqueue_event_Type;
1758
1759#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1760
1761typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 PyObject_HEAD
1763 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001764} kqueue_queue_Object;
1765
1766static PyTypeObject kqueue_queue_Type;
1767
1768#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1769
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001770#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1771# error uintptr_t does not match void *!
1772#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1773# define T_UINTPTRT T_ULONGLONG
1774# define T_INTPTRT T_LONGLONG
1775# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1776# define UINTPTRT_FMT_UNIT "K"
1777# define INTPTRT_FMT_UNIT "L"
1778#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1779# define T_UINTPTRT T_ULONG
1780# define T_INTPTRT T_LONG
1781# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1782# define UINTPTRT_FMT_UNIT "k"
1783# define INTPTRT_FMT_UNIT "l"
1784#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1785# define T_UINTPTRT T_UINT
1786# define T_INTPTRT T_INT
1787# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1788# define UINTPTRT_FMT_UNIT "I"
1789# define INTPTRT_FMT_UNIT "i"
1790#else
1791# error uintptr_t does not match int, long, or long long!
1792#endif
1793
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001794/*
1795 * kevent is not standard and its members vary across BSDs.
1796 */
1797#if !defined(__OpenBSD__)
Christian Heimesaf01f662013-12-21 16:19:10 +01001798# define IDENT_TYPE T_UINTPTRT
Benjamin Petersonca470632016-09-06 13:47:26 -07001799# define IDENT_CAST intptr_t
Christian Heimesaf01f662013-12-21 16:19:10 +01001800# define DATA_TYPE T_INTPTRT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001801# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Christian Heimesaf01f662013-12-21 16:19:10 +01001802# define IDENT_AsType PyLong_AsUintptr_t
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001803#else
Christian Heimesaf01f662013-12-21 16:19:10 +01001804# define IDENT_TYPE T_UINT
1805# define IDENT_CAST int
1806# define DATA_TYPE T_INT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001807# define DATA_FMT_UNIT "i"
Christian Heimesaf01f662013-12-21 16:19:10 +01001808# define IDENT_AsType PyLong_AsUnsignedLong
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001809#endif
1810
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001811/* Unfortunately, we can't store python objects in udata, because
1812 * kevents in the kernel can be removed without warning, which would
1813 * forever lose the refcount on the object stored with it.
1814 */
1815
1816#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1817static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001818 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 {"filter", T_SHORT, KQ_OFF(e.filter)},
1820 {"flags", T_USHORT, KQ_OFF(e.flags)},
1821 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001822 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1824 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001825};
1826#undef KQ_OFF
1827
1828static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001829
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001830kqueue_event_repr(kqueue_event_Object *s)
1831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 char buf[1024];
1833 PyOS_snprintf(
1834 buf, sizeof(buf),
1835 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1836 "data=0x%zd udata=%p>",
1837 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1838 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1839 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001840}
1841
1842static int
1843kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 PyObject *pfd;
1846 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1847 "data", "udata", NULL};
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001848 static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1853 &pfd, &(self->e.filter), &(self->e.flags),
1854 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1855 return -1;
1856 }
1857
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001858 if (PyLong_Check(pfd)
1859#if IDENT_TYPE == T_UINT
Christian Heimesaf01f662013-12-21 16:19:10 +01001860 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001861#endif
1862 ) {
1863 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 }
1865 else {
1866 self->e.ident = PyObject_AsFileDescriptor(pfd);
1867 }
1868 if (PyErr_Occurred()) {
1869 return -1;
1870 }
1871 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001872}
1873
1874static PyObject *
1875kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001877{
Benjamin Petersonca470632016-09-06 13:47:26 -07001878 intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 if (!kqueue_event_Check(o)) {
1881 if (op == Py_EQ || op == Py_NE) {
1882 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1883 Py_INCREF(res);
1884 return res;
1885 }
1886 PyErr_Format(PyExc_TypeError,
1887 "can't compare %.200s to %.200s",
1888 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1889 return NULL;
1890 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001891 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 ((result = s->e.filter - o->e.filter) == 0) &&
1893 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001894 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 ((result = s->e.data - o->e.data) == 0) &&
1896 ((result = s->e.udata - o->e.udata) == 0)
1897 ) {
1898 result = 0;
1899 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 switch (op) {
Guido van Rossumee07b942013-12-06 17:46:22 -08001902 case Py_EQ:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 result = (result == 0);
1904 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001905 case Py_NE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 result = (result != 0);
1907 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001908 case Py_LE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 result = (result <= 0);
1910 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001911 case Py_GE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 result = (result >= 0);
1913 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001914 case Py_LT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 result = (result < 0);
1916 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001917 case Py_GT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 result = (result > 0);
1919 break;
1920 }
1921 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001922}
1923
1924static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 PyVarObject_HEAD_INIT(NULL, 0)
1926 "select.kevent", /* tp_name */
1927 sizeof(kqueue_event_Object), /* tp_basicsize */
1928 0, /* tp_itemsize */
1929 0, /* tp_dealloc */
1930 0, /* tp_print */
1931 0, /* tp_getattr */
1932 0, /* tp_setattr */
1933 0, /* tp_reserved */
1934 (reprfunc)kqueue_event_repr, /* tp_repr */
1935 0, /* tp_as_number */
1936 0, /* tp_as_sequence */
1937 0, /* tp_as_mapping */
1938 0, /* tp_hash */
1939 0, /* tp_call */
1940 0, /* tp_str */
1941 0, /* tp_getattro */
1942 0, /* tp_setattro */
1943 0, /* tp_as_buffer */
1944 Py_TPFLAGS_DEFAULT, /* tp_flags */
1945 kqueue_event_doc, /* tp_doc */
1946 0, /* tp_traverse */
1947 0, /* tp_clear */
1948 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1949 0, /* tp_weaklistoffset */
1950 0, /* tp_iter */
1951 0, /* tp_iternext */
1952 0, /* tp_methods */
1953 kqueue_event_members, /* tp_members */
1954 0, /* tp_getset */
1955 0, /* tp_base */
1956 0, /* tp_dict */
1957 0, /* tp_descr_get */
1958 0, /* tp_descr_set */
1959 0, /* tp_dictoffset */
1960 (initproc)kqueue_event_init, /* tp_init */
1961 0, /* tp_alloc */
1962 0, /* tp_new */
1963 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001964};
1965
1966static PyObject *
1967kqueue_queue_err_closed(void)
1968{
Victor Stinner13423c32013-08-22 00:19:50 +02001969 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001971}
1972
1973static int
1974kqueue_queue_internal_close(kqueue_queue_Object *self)
1975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 int save_errno = 0;
1977 if (self->kqfd >= 0) {
1978 int kqfd = self->kqfd;
1979 self->kqfd = -1;
1980 Py_BEGIN_ALLOW_THREADS
1981 if (close(kqfd) < 0)
1982 save_errno = errno;
1983 Py_END_ALLOW_THREADS
1984 }
1985 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001986}
1987
1988static PyObject *
1989newKqueue_Object(PyTypeObject *type, SOCKET fd)
1990{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 kqueue_queue_Object *self;
1992 assert(type != NULL && type->tp_alloc != NULL);
1993 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1994 if (self == NULL) {
1995 return NULL;
1996 }
1997
1998 if (fd == -1) {
1999 Py_BEGIN_ALLOW_THREADS
2000 self->kqfd = kqueue();
2001 Py_END_ALLOW_THREADS
2002 }
2003 else {
2004 self->kqfd = fd;
2005 }
2006 if (self->kqfd < 0) {
2007 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002008 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 return NULL;
2010 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02002011
2012 if (fd == -1) {
2013 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
2014 Py_DECREF(self);
2015 return NULL;
2016 }
2017 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002019}
2020
2021static PyObject *
2022kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2023{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002024 if (PyTuple_GET_SIZE(args) ||
2025 (kwds != NULL && PyDict_GET_SIZE(kwds))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 PyErr_SetString(PyExc_ValueError,
2027 "select.kqueue doesn't accept arguments");
2028 return NULL;
2029 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002032}
2033
2034static void
2035kqueue_queue_dealloc(kqueue_queue_Object *self)
2036{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 kqueue_queue_internal_close(self);
2038 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002039}
2040
2041static PyObject*
2042kqueue_queue_close(kqueue_queue_Object *self)
2043{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 errno = kqueue_queue_internal_close(self);
2045 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002046 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 return NULL;
2048 }
2049 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002050}
2051
2052PyDoc_STRVAR(kqueue_queue_close_doc,
2053"close() -> None\n\
2054\n\
2055Close the kqueue control file descriptor. Further operations on the kqueue\n\
2056object will raise an exception.");
2057
2058static PyObject*
2059kqueue_queue_get_closed(kqueue_queue_Object *self)
2060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 if (self->kqfd < 0)
2062 Py_RETURN_TRUE;
2063 else
2064 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002065}
2066
2067static PyObject*
2068kqueue_queue_fileno(kqueue_queue_Object *self)
2069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 if (self->kqfd < 0)
2071 return kqueue_queue_err_closed();
2072 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002073}
2074
2075PyDoc_STRVAR(kqueue_queue_fileno_doc,
2076"fileno() -> int\n\
2077\n\
2078Return the kqueue control file descriptor.");
2079
2080static PyObject*
2081kqueue_queue_fromfd(PyObject *cls, PyObject *args)
2082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2086 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002089}
2090
2091PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2092"fromfd(fd) -> kqueue\n\
2093\n\
2094Create a kqueue object from a given control fd.");
2095
2096static PyObject *
2097kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 int nevents = 0;
2100 int gotevents = 0;
2101 int nchanges = 0;
2102 int i = 0;
2103 PyObject *otimeout = NULL;
2104 PyObject *ch = NULL;
2105 PyObject *it = NULL, *ei = NULL;
2106 PyObject *result = NULL;
2107 struct kevent *evl = NULL;
2108 struct kevent *chl = NULL;
Victor Stinner4448c082015-03-31 11:48:34 +02002109 struct timespec timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 struct timespec *ptimeoutspec;
Victor Stinner4448c082015-03-31 11:48:34 +02002111 _PyTime_t timeout, deadline = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 if (self->kqfd < 0)
2114 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2117 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (nevents < 0) {
2120 PyErr_Format(PyExc_ValueError,
2121 "Length of eventlist must be 0 or positive, got %d",
2122 nevents);
2123 return NULL;
2124 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 if (otimeout == Py_None || otimeout == NULL) {
2127 ptimeoutspec = NULL;
2128 }
Victor Stinnerc3378382015-03-28 05:07:51 +01002129 else {
Victor Stinner4448c082015-03-31 11:48:34 +02002130 if (_PyTime_FromSecondsObject(&timeout,
Victor Stinner869e1772015-03-30 03:49:14 +02002131 otimeout, _PyTime_ROUND_CEILING) < 0) {
Victor Stinnerc3378382015-03-28 05:07:51 +01002132 PyErr_Format(PyExc_TypeError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002133 "timeout argument must be a number "
Victor Stinnerc3378382015-03-28 05:07:51 +01002134 "or None, got %.200s",
2135 Py_TYPE(otimeout)->tp_name);
2136 return NULL;
2137 }
2138
Victor Stinner4448c082015-03-31 11:48:34 +02002139 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002140 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002141
Victor Stinner4448c082015-03-31 11:48:34 +02002142 if (timeoutspec.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 PyErr_SetString(PyExc_ValueError,
2144 "timeout must be positive or None");
2145 return NULL;
2146 }
Victor Stinner4448c082015-03-31 11:48:34 +02002147 ptimeoutspec = &timeoutspec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 if (ch != NULL && ch != Py_None) {
2151 it = PyObject_GetIter(ch);
2152 if (it == NULL) {
2153 PyErr_SetString(PyExc_TypeError,
2154 "changelist is not iterable");
2155 return NULL;
2156 }
2157 nchanges = PyObject_Size(ch);
2158 if (nchanges < 0) {
2159 goto error;
2160 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00002161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 chl = PyMem_New(struct kevent, nchanges);
2163 if (chl == NULL) {
2164 PyErr_NoMemory();
2165 goto error;
2166 }
2167 i = 0;
2168 while ((ei = PyIter_Next(it)) != NULL) {
2169 if (!kqueue_event_Check(ei)) {
2170 Py_DECREF(ei);
2171 PyErr_SetString(PyExc_TypeError,
2172 "changelist must be an iterable of "
2173 "select.kevent objects");
2174 goto error;
2175 } else {
2176 chl[i++] = ((kqueue_event_Object *)ei)->e;
2177 }
2178 Py_DECREF(ei);
2179 }
2180 }
2181 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 /* event list */
2184 if (nevents) {
2185 evl = PyMem_New(struct kevent, nevents);
2186 if (evl == NULL) {
2187 PyErr_NoMemory();
2188 goto error;
2189 }
2190 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002191
Victor Stinner4448c082015-03-31 11:48:34 +02002192 if (ptimeoutspec)
2193 deadline = _PyTime_GetMonotonicClock() + timeout;
2194
2195 do {
2196 Py_BEGIN_ALLOW_THREADS
2197 errno = 0;
2198 gotevents = kevent(self->kqfd, chl, nchanges,
2199 evl, nevents, ptimeoutspec);
2200 Py_END_ALLOW_THREADS
2201
2202 if (errno != EINTR)
2203 break;
2204
2205 /* kevent() was interrupted by a signal */
2206 if (PyErr_CheckSignals())
2207 goto error;
2208
2209 if (ptimeoutspec) {
2210 timeout = deadline - _PyTime_GetMonotonicClock();
2211 if (timeout < 0) {
2212 gotevents = 0;
2213 break;
2214 }
2215 if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1)
2216 goto error;
2217 /* retry kevent() with the recomputed timeout */
2218 }
2219 } while (1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 if (gotevents == -1) {
2222 PyErr_SetFromErrno(PyExc_OSError);
2223 goto error;
2224 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 result = PyList_New(gotevents);
2227 if (result == NULL) {
2228 goto error;
2229 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 for (i = 0; i < gotevents; i++) {
2232 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2235 if (ch == NULL) {
2236 goto error;
2237 }
2238 ch->e = evl[i];
2239 PyList_SET_ITEM(result, i, (PyObject *)ch);
2240 }
2241 PyMem_Free(chl);
2242 PyMem_Free(evl);
2243 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002244
2245 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 PyMem_Free(chl);
2247 PyMem_Free(evl);
2248 Py_XDECREF(result);
2249 Py_XDECREF(it);
2250 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002251}
2252
2253PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002254"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002255\n\
2256Calls the kernel kevent function.\n\
2257- changelist must be a list of kevent objects describing the changes\n\
2258 to be made to the kernel's watch list or None.\n\
2259- max_events lets you specify the maximum number of events that the\n\
2260 kernel will return.\n\
2261- timeout is the maximum time to wait in seconds, or else None,\n\
2262 to wait forever. timeout accepts floats for smaller timeouts, too.");
2263
2264
2265static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2267 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2268 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2269 kqueue_queue_close_doc},
2270 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2271 kqueue_queue_fileno_doc},
2272 {"control", (PyCFunction)kqueue_queue_control,
2273 METH_VARARGS , kqueue_queue_control_doc},
2274 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002275};
2276
2277static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 {"closed", (getter)kqueue_queue_get_closed, NULL,
2279 "True if the kqueue handler is closed"},
2280 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002281};
2282
2283PyDoc_STRVAR(kqueue_queue_doc,
2284"Kqueue syscall wrapper.\n\
2285\n\
2286For example, to start watching a socket for input:\n\
2287>>> kq = kqueue()\n\
2288>>> sock = socket()\n\
2289>>> sock.connect((host, port))\n\
2290>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2291\n\
2292To wait one second for it to become writeable:\n\
2293>>> kq.control(None, 1, 1000)\n\
2294\n\
2295To stop listening:\n\
2296>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2297
2298static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 PyVarObject_HEAD_INIT(NULL, 0)
2300 "select.kqueue", /* tp_name */
2301 sizeof(kqueue_queue_Object), /* tp_basicsize */
2302 0, /* tp_itemsize */
2303 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2304 0, /* tp_print */
2305 0, /* tp_getattr */
2306 0, /* tp_setattr */
2307 0, /* tp_reserved */
2308 0, /* tp_repr */
2309 0, /* tp_as_number */
2310 0, /* tp_as_sequence */
2311 0, /* tp_as_mapping */
2312 0, /* tp_hash */
2313 0, /* tp_call */
2314 0, /* tp_str */
2315 0, /* tp_getattro */
2316 0, /* tp_setattro */
2317 0, /* tp_as_buffer */
2318 Py_TPFLAGS_DEFAULT, /* tp_flags */
2319 kqueue_queue_doc, /* tp_doc */
2320 0, /* tp_traverse */
2321 0, /* tp_clear */
2322 0, /* tp_richcompare */
2323 0, /* tp_weaklistoffset */
2324 0, /* tp_iter */
2325 0, /* tp_iternext */
2326 kqueue_queue_methods, /* tp_methods */
2327 0, /* tp_members */
2328 kqueue_queue_getsetlist, /* tp_getset */
2329 0, /* tp_base */
2330 0, /* tp_dict */
2331 0, /* tp_descr_get */
2332 0, /* tp_descr_set */
2333 0, /* tp_dictoffset */
2334 0, /* tp_init */
2335 0, /* tp_alloc */
2336 kqueue_queue_new, /* tp_new */
2337 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002338};
2339
2340#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002341
2342
2343
2344
2345
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002346/* ************************************************************************ */
2347
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002348PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002349"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2350\n\
2351Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002352The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002353rlist -- wait until ready for reading\n\
2354wlist -- wait until ready for writing\n\
2355xlist -- wait for an ``exceptional condition''\n\
2356If only one kind of condition is required, pass [] for the other lists.\n\
2357A file descriptor is either a socket or file object, or a small integer\n\
2358gotten from a fileno() method call on one of those.\n\
2359\n\
2360The optional 4th argument specifies a timeout in seconds; it may be\n\
2361a floating point number to specify fractions of seconds. If it is absent\n\
2362or None, the call will never time out.\n\
2363\n\
2364The return value is a tuple of three lists corresponding to the first three\n\
2365arguments; each contains the subset of the corresponding file descriptors\n\
2366that are ready.\n\
2367\n\
2368*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002369On Windows, only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002370descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002371
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002372static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002374#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002376#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002377#ifdef HAVE_SYS_DEVPOLL_H
2378 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2379#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002381};
2382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002383PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002384"This module supports asynchronous I/O on multiple file descriptors.\n\
2385\n\
2386*** IMPORTANT NOTICE ***\n\
Benjamin Petersonb397e3b2015-10-10 19:32:20 -07002387On Windows, only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002388
Martin v. Löwis1a214512008-06-11 05:26:20 +00002389
2390static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 PyModuleDef_HEAD_INIT,
2392 "select",
2393 module_doc,
2394 -1,
2395 select_methods,
2396 NULL,
2397 NULL,
2398 NULL,
2399 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002400};
2401
Jesus Cead8b9ae62011-11-14 19:07:41 +01002402
2403
2404
Mark Hammond62b1ab12002-07-23 06:31:15 +00002405PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002406PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 PyObject *m;
2409 m = PyModule_Create(&selectmodule);
2410 if (m == NULL)
2411 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002412
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002413 Py_INCREF(PyExc_OSError);
2414 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002415
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002416#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002417#ifdef HAVE_BROKEN_PIPE_BUF
2418#undef PIPE_BUF
2419#define PIPE_BUF 512
2420#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002421 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002422#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002423
Charles-François Natali986a56c2013-01-19 12:19:10 +01002424#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002425#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 if (select_have_broken_poll()) {
2427 if (PyObject_DelAttrString(m, "poll") == -1) {
2428 PyErr_Clear();
2429 }
2430 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002431#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002433#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 if (PyType_Ready(&poll_Type) < 0)
2435 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002436 PyModule_AddIntMacro(m, POLLIN);
2437 PyModule_AddIntMacro(m, POLLPRI);
2438 PyModule_AddIntMacro(m, POLLOUT);
2439 PyModule_AddIntMacro(m, POLLERR);
2440 PyModule_AddIntMacro(m, POLLHUP);
2441 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002442
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002443#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002444 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002445#endif
2446#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002447 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002448#endif
2449#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002450 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002451#endif
2452#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002453 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002454#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002455#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002456 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002457#endif
Berker Peksagfe8d9662016-07-19 21:09:26 +03002458#ifdef POLLRDHUP
2459 /* Kernel 2.6.17+ */
2460 PyModule_AddIntMacro(m, POLLRDHUP);
2461#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002463#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002464
Jesus Cead8b9ae62011-11-14 19:07:41 +01002465#ifdef HAVE_SYS_DEVPOLL_H
2466 if (PyType_Ready(&devpoll_Type) < 0)
2467 return NULL;
2468#endif
2469
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002470#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2472 if (PyType_Ready(&pyEpoll_Type) < 0)
2473 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 Py_INCREF(&pyEpoll_Type);
2476 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002477
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002478 PyModule_AddIntMacro(m, EPOLLIN);
2479 PyModule_AddIntMacro(m, EPOLLOUT);
2480 PyModule_AddIntMacro(m, EPOLLPRI);
2481 PyModule_AddIntMacro(m, EPOLLERR);
2482 PyModule_AddIntMacro(m, EPOLLHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002483#ifdef EPOLLRDHUP
2484 /* Kernel 2.6.17 */
Benjamin Peterson96e97162016-07-18 21:47:39 -07002485 PyModule_AddIntMacro(m, EPOLLRDHUP);
Berker Peksage1d22fd2016-08-08 13:39:43 +03002486#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002487 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002488#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002490 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002491#endif
Benjamin Peterson0715ce32016-07-18 22:02:44 -07002492#ifdef EPOLLEXCLUSIVE
2493 PyModule_AddIntMacro(m, EPOLLEXCLUSIVE);
2494#endif
Zachary Ware3e776772015-08-01 21:34:05 -05002495
2496#ifdef EPOLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002497 PyModule_AddIntMacro(m, EPOLLRDNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002498#endif
2499#ifdef EPOLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002500 PyModule_AddIntMacro(m, EPOLLRDBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002501#endif
2502#ifdef EPOLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002503 PyModule_AddIntMacro(m, EPOLLWRNORM);
Zachary Ware3e776772015-08-01 21:34:05 -05002504#endif
2505#ifdef EPOLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002506 PyModule_AddIntMacro(m, EPOLLWRBAND);
Zachary Ware3e776772015-08-01 21:34:05 -05002507#endif
2508#ifdef EPOLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002509 PyModule_AddIntMacro(m, EPOLLMSG);
Zachary Ware3e776772015-08-01 21:34:05 -05002510#endif
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002511
Benjamin Peterson95c16622011-12-27 15:36:32 -06002512#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002513 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002514#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002515#endif /* HAVE_EPOLL */
2516
2517#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 kqueue_event_Type.tp_new = PyType_GenericNew;
2519 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2520 if(PyType_Ready(&kqueue_event_Type) < 0)
2521 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 Py_INCREF(&kqueue_event_Type);
2524 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2527 if(PyType_Ready(&kqueue_queue_Type) < 0)
2528 return NULL;
2529 Py_INCREF(&kqueue_queue_Type);
2530 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2531
2532 /* event filters */
2533 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2534 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002535#ifdef EVFILT_AIO
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
Berker Peksag7ec64562016-09-14 18:16:59 +03002537#endif
2538#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002540#endif
2541#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Berker Peksag7ec64562016-09-14 18:16:59 +03002543#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002544#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002545 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002546#endif
Berker Peksag7ec64562016-09-14 18:16:59 +03002547#ifdef EVFILT_SIGNAL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
Berker Peksag7ec64562016-09-14 18:16:59 +03002549#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002552 /* event flags */
2553 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2554 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2555 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2556 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2557 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2558 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002559
Berker Peksag7ec64562016-09-14 18:16:59 +03002560#ifdef EV_SYSFLAGS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
Berker Peksag7ec64562016-09-14 18:16:59 +03002562#endif
2563#ifdef EV_FLAG1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Berker Peksag7ec64562016-09-14 18:16:59 +03002565#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002567 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2568 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 /* READ WRITE filter flag */
Berker Peksag7ec64562016-09-14 18:16:59 +03002571#ifdef NOTE_LOWAT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Berker Peksag7ec64562016-09-14 18:16:59 +03002573#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 /* VNODE filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002576#ifdef EVFILT_VNODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2578 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2579 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2580 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2581 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2582 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2583 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Berker Peksag7ec64562016-09-14 18:16:59 +03002584#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 /* PROC filter flags */
Berker Peksag7ec64562016-09-14 18:16:59 +03002587#ifdef EVFILT_PROC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002588 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2589 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2590 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2591 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2592 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2595 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2596 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
Berker Peksag7ec64562016-09-14 18:16:59 +03002597#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598
2599 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002600#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2602 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2603 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002604#endif
2605
2606#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002608}