blob: ffaf865df2b750061edc94d85d7fb0e356e52dfc [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
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00007#include "Python.h"
Christian Heimes4fbc72b2008-03-22 00:47:35 +00008#include <structmember.h>
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Jesus Cead8b9ae62011-11-14 19:07:41 +010010#ifdef HAVE_SYS_DEVPOLL_H
11#include <sys/resource.h>
12#include <sys/devpoll.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#endif
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018#ifdef __APPLE__
19 /* Perform runtime testing for a broken poll on OSX to make it easier
20 * to use the same binary on multiple releases of the OS.
21 */
22#undef HAVE_BROKEN_POLL
23#endif
24
Tim Petersd92dfe02000-12-12 01:18:41 +000025/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
26 64 is too small (too many people have bumped into that limit).
27 Here we boost it.
28 Users who want even more than the boosted limit should #define
29 FD_SETSIZE higher before this; e.g., via compiler /D switch.
30*/
31#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
32#define FD_SETSIZE 512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033#endif
Tim Petersd92dfe02000-12-12 01:18:41 +000034
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000035#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000036#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000037#elif defined(HAVE_SYS_POLL_H)
38#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000039#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000040
Guido van Rossum37273171996-12-09 18:47:43 +000041#ifdef __sgi
42/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000043extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000044#endif
45
Thomas Wouters0e3f5912006-08-11 14:57:12 +000046#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000048#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049
Guido van Rossum6f489d91996-06-28 20:15:15 +000050#ifdef MS_WINDOWS
Christian Heimesc36625b2008-01-04 13:33:00 +000051# define WIN32_LEAN_AND_MEAN
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052# include <winsock.h>
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000053#else
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054# define SOCKET int
Guido van Rossumbcc20741998-08-04 22:53:56 +000055#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000056
Barry Warsawc1cb3601996-12-12 22:16:21 +000057/* list of Python objects and their file descriptor */
58typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 PyObject *obj; /* owned reference */
60 SOCKET fd;
61 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000062} pylist;
63
Barry Warsawc1cb3601996-12-12 22:16:21 +000064static void
Tim Peters4b046c22001-08-16 21:59:46 +000065reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 int i;
68 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +020069 Py_CLEAR(fd2obj[i].obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 }
71 fd2obj[0].sentinel = -1;
Barry Warsawc1cb3601996-12-12 22:16:21 +000072}
73
74
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000075/* returns -1 and sets the Python exception if an error occurred, otherwise
76 returns a number >= 0
77*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000078static int
Brett Cannon62dba4c2003-09-10 19:37:42 +000079seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +000080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 int max = -1;
82 int index = 0;
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010083 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyObject* fast_seq = NULL;
85 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
88 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000089
Benjamin Petersone0edb8b2010-06-27 23:49:45 +000090 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 if (!fast_seq)
92 return -1;
93
Antoine Pitroue4ad37e2012-11-01 20:13:54 +010094 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 SOCKET v;
96
97 /* any intervening fileno() calls could decr this refcnt */
98 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
Jesus Cea62a5c322012-07-19 21:31:26 +020099 goto finally;
Brett Cannon62dba4c2003-09-10 19:37:42 +0000100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 Py_INCREF(o);
102 v = PyObject_AsFileDescriptor( o );
103 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000105#if defined(_MSC_VER)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 max = 0; /* not used for Win32 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107#else /* !_MSC_VER */
Charles-François Nataliaa26b272011-08-28 17:51:43 +0200108 if (!_PyIsSelectable_fd(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 PyErr_SetString(PyExc_ValueError,
110 "filedescriptor out of range in select()");
111 goto finally;
112 }
113 if (v > max)
114 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115#endif /* _MSC_VER */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 /* add object and its file descriptor to the list */
119 if (index >= FD_SETSIZE) {
120 PyErr_SetString(PyExc_ValueError,
121 "too many file descriptors in select()");
122 goto finally;
123 }
124 fd2obj[index].obj = o;
125 fd2obj[index].fd = v;
126 fd2obj[index].sentinel = 0;
127 fd2obj[++index].sentinel = -1;
128 }
129 Py_DECREF(fast_seq);
130 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000131
132 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 Py_XDECREF(o);
134 Py_DECREF(fast_seq);
135 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000136}
137
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000138/* returns NULL and sets the Python exception if an error occurred */
139static PyObject *
Tim Peters4b046c22001-08-16 21:59:46 +0000140set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
Guido van Rossumed233a51992-06-23 09:07:03 +0000141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 int i, j, count=0;
143 PyObject *list, *o;
144 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
147 if (FD_ISSET(fd2obj[j].fd, set))
148 count++;
149 }
150 list = PyList_New(count);
151 if (!list)
152 return NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 i = 0;
155 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
156 fd = fd2obj[j].fd;
157 if (FD_ISSET(fd, set)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 o = fd2obj[j].obj;
159 fd2obj[j].obj = NULL;
160 /* transfer ownership */
161 if (PyList_SetItem(list, i, o) < 0)
162 goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 i++;
165 }
166 }
167 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000168 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 Py_DECREF(list);
170 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000171}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000172
Barry Warsawb44740f2001-08-16 16:52:59 +0000173#undef SELECT_USES_HEAP
174#if FD_SETSIZE > 1024
175#define SELECT_USES_HEAP
176#endif /* FD_SETSIZE > 1024 */
177
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000178static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000179select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000180{
Barry Warsawb44740f2001-08-16 16:52:59 +0000181#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000183#else /* !SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 /* XXX: All this should probably be implemented as follows:
185 * - find the highest descriptor we're interested in
186 * - add one
187 * - that's the size
188 * See: Stevens, APitUE, $12.5.1
189 */
190 pylist rfd2obj[FD_SETSIZE + 1];
191 pylist wfd2obj[FD_SETSIZE + 1];
192 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000193#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 PyObject *ifdlist, *ofdlist, *efdlist;
195 PyObject *ret = NULL;
196 PyObject *tout = Py_None;
197 fd_set ifdset, ofdset, efdset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 struct timeval tv, *tvp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 int imax, omax, emax, max;
200 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 /* convert arguments */
203 if (!PyArg_UnpackTuple(args, "select", 3, 4,
204 &ifdlist, &ofdlist, &efdlist, &tout))
205 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 if (tout == Py_None)
208 tvp = (struct timeval *)0;
209 else if (!PyNumber_Check(tout)) {
210 PyErr_SetString(PyExc_TypeError,
211 "timeout must be a float or None");
212 return NULL;
213 }
214 else {
Victor Stinner5a8e5792014-02-18 01:35:40 +0100215 /* On OpenBSD 5.4, timeval.tv_sec is a long.
216 * Example: long is 64-bit, whereas time_t is 32-bit. */
Victor Stinnerb2a37732012-03-14 00:20:51 +0100217 time_t sec;
Victor Stinner5a8e5792014-02-18 01:35:40 +0100218 /* On OS X 64-bit, timeval.tv_usec is an int (and thus still 4
219 bytes as required), but no longer defined by a long. */
220 long usec;
221 if (_PyTime_ObjectToTimeval(tout, &sec, &usec,
Victor Stinner3c1b3792014-02-17 00:02:43 +0100222 _PyTime_ROUND_UP) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 return NULL;
Victor Stinner5a8e5792014-02-18 01:35:40 +0100224#ifdef MS_WINDOWS
225 /* On Windows, timeval.tv_sec is a long (32 bit),
226 * whereas time_t can be 64-bit. */
Victor Stinnerb2a37732012-03-14 00:20:51 +0100227 assert(sizeof(tv.tv_sec) == sizeof(long));
228#if SIZEOF_TIME_T > SIZEOF_LONG
229 if (sec > LONG_MAX) {
230 PyErr_SetString(PyExc_OverflowError,
231 "timeout is too large");
232 return NULL;
233 }
234#endif
Victor Stinner329e4922014-02-18 09:30:33 +0100235 tv.tv_sec = (long)sec;
Victor Stinnerb2a37732012-03-14 00:20:51 +0100236#else
Victor Stinner5a8e5792014-02-18 01:35:40 +0100237 assert(sizeof(tv.tv_sec) >= sizeof(sec));
Victor Stinner5a8e5792014-02-18 01:35:40 +0100238 tv.tv_sec = sec;
Victor Stinner329e4922014-02-18 09:30:33 +0100239#endif
Victor Stinner5a8e5792014-02-18 01:35:40 +0100240 tv.tv_usec = usec;
Victor Stinner5d272cc2012-03-13 13:35:55 +0100241 if (tv.tv_sec < 0) {
242 PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 return NULL;
244 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 tvp = &tv;
246 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000247
Guido van Rossumed233a51992-06-23 09:07:03 +0000248
Barry Warsawb44740f2001-08-16 16:52:59 +0000249#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 /* Allocate memory for the lists */
251 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
252 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
255 if (rfd2obj) PyMem_DEL(rfd2obj);
256 if (wfd2obj) PyMem_DEL(wfd2obj);
257 if (efd2obj) PyMem_DEL(efd2obj);
258 return PyErr_NoMemory();
259 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000260#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 /* Convert sequences to fd_sets, and get maximum fd number
262 * propagates the Python exception set in seq2set()
263 */
264 rfd2obj[0].sentinel = -1;
265 wfd2obj[0].sentinel = -1;
266 efd2obj[0].sentinel = -1;
267 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
268 goto finally;
269 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
270 goto finally;
271 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
272 goto finally;
273 max = imax;
274 if (omax > max) max = omax;
275 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 Py_BEGIN_ALLOW_THREADS
278 n = select(max, &ifdset, &ofdset, &efdset, tvp);
279 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000280
Thomas Heller106f4c72002-09-24 16:51:00 +0000281#ifdef MS_WINDOWS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 if (n == SOCKET_ERROR) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200283 PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000285#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 if (n < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200287 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Thomas Heller106f4c72002-09-24 16:51:00 +0000289#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 else {
291 /* any of these three calls can raise an exception. it's more
292 convenient to test for this after all three calls... but
293 is that acceptable?
294 */
295 ifdlist = set2list(&ifdset, rfd2obj);
296 ofdlist = set2list(&ofdset, wfd2obj);
297 efdlist = set2list(&efdset, efd2obj);
298 if (PyErr_Occurred())
299 ret = NULL;
300 else
301 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000302
Victor Stinnerbbf8ce52013-07-09 00:49:03 +0200303 Py_XDECREF(ifdlist);
304 Py_XDECREF(ofdlist);
305 Py_XDECREF(efdlist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 }
307
Barry Warsawc1cb3601996-12-12 22:16:21 +0000308 finally:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 reap_obj(rfd2obj);
310 reap_obj(wfd2obj);
311 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000312#ifdef SELECT_USES_HEAP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyMem_DEL(rfd2obj);
314 PyMem_DEL(wfd2obj);
315 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000316#endif /* SELECT_USES_HEAP */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000318}
319
Nicholas Bastine62c5c82004-03-21 23:45:42 +0000320#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321/*
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000322 * poll() support
323 */
324
325typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 PyObject_HEAD
327 PyObject *dict;
328 int ufd_uptodate;
329 int ufd_len;
330 struct pollfd *ufds;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300331 int poll_running;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000332} pollObject;
333
Jeremy Hylton938ace62002-07-17 16:30:39 +0000334static PyTypeObject poll_Type;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336/* Update the malloc'ed array of pollfds to match the dictionary
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000337 contained within a pollObject. Return 1 on success, 0 on an error.
338*/
339
340static int
341update_ufd_array(pollObject *self)
342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 Py_ssize_t i, pos;
344 PyObject *key, *value;
345 struct pollfd *old_ufds = self->ufds;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 self->ufd_len = PyDict_Size(self->dict);
348 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
349 if (self->ufds == NULL) {
350 self->ufds = old_ufds;
351 PyErr_NoMemory();
352 return 0;
353 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 i = pos = 0;
356 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200357 assert(i < self->ufd_len);
358 /* Never overflow */
359 self->ufds[i].fd = (int)PyLong_AsLong(key);
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200360 self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 i++;
362 }
Serhiy Storchaka78980432013-01-15 01:12:17 +0200363 assert(i == self->ufd_len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 self->ufd_uptodate = 1;
365 return 1;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000366}
367
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200368static int
369ushort_converter(PyObject *obj, void *ptr)
370{
371 unsigned long uval;
372
373 uval = PyLong_AsUnsignedLong(obj);
374 if (uval == (unsigned long)-1 && PyErr_Occurred())
375 return 0;
376 if (uval > USHRT_MAX) {
377 PyErr_SetString(PyExc_OverflowError,
378 "Python int too large for C unsigned short");
379 return 0;
380 }
381
382 *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
383 return 1;
384}
385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000386PyDoc_STRVAR(poll_register_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000387"register(fd [, eventmask] ) -> None\n\n\
388Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000389fd -- either an integer, or an object with a fileno() method returning an\n\
390 int.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000391events -- an optional bitmask describing the type of events to check for");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000392
393static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394poll_register(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200397 int fd;
398 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 int err;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000400
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200401 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 fd = PyObject_AsFileDescriptor(o);
405 if (fd == -1) return NULL;
Guido van Rossuma0dfc852001-10-25 20:18:35 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 /* Add entry to the internal dictionary: the key is the
408 file descriptor, and the value is the event mask. */
409 key = PyLong_FromLong(fd);
410 if (key == NULL)
411 return NULL;
412 value = PyLong_FromLong(events);
413 if (value == NULL) {
414 Py_DECREF(key);
415 return NULL;
416 }
417 err = PyDict_SetItem(self->dict, key, value);
418 Py_DECREF(key);
419 Py_DECREF(value);
420 if (err < 0)
421 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 self->ufd_uptodate = 0;
424
425 Py_INCREF(Py_None);
426 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000427}
428
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000429PyDoc_STRVAR(poll_modify_doc,
430"modify(fd, eventmask) -> None\n\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +0000431Modify an already registered file descriptor.\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000432fd -- either an integer, or an object with a fileno() method returning an\n\
433 int.\n\
434events -- an optional bitmask describing the type of events to check for");
435
436static PyObject *
437poll_modify(pollObject *self, PyObject *args)
438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 PyObject *o, *key, *value;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200440 int fd;
441 unsigned short events;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 int err;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000443
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200444 if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 fd = PyObject_AsFileDescriptor(o);
448 if (fd == -1) return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 /* Modify registered fd */
451 key = PyLong_FromLong(fd);
452 if (key == NULL)
453 return NULL;
454 if (PyDict_GetItem(self->dict, key) == NULL) {
455 errno = ENOENT;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200456 PyErr_SetFromErrno(PyExc_OSError);
Jesus Cea62a5c322012-07-19 21:31:26 +0200457 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 return NULL;
459 }
460 value = PyLong_FromLong(events);
461 if (value == NULL) {
462 Py_DECREF(key);
463 return NULL;
464 }
465 err = PyDict_SetItem(self->dict, key, value);
466 Py_DECREF(key);
467 Py_DECREF(value);
468 if (err < 0)
469 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 self->ufd_uptodate = 0;
472
473 Py_INCREF(Py_None);
474 return Py_None;
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000475}
476
477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000478PyDoc_STRVAR(poll_unregister_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000479"unregister(fd) -> None\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000480Remove a file descriptor being tracked by the polling object.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000481
482static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483poll_unregister(pollObject *self, PyObject *o)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 PyObject *key;
486 int fd;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 fd = PyObject_AsFileDescriptor( o );
489 if (fd == -1)
490 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 /* Check whether the fd is already in the array */
493 key = PyLong_FromLong(fd);
494 if (key == NULL)
495 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 if (PyDict_DelItem(self->dict, key) == -1) {
498 Py_DECREF(key);
499 /* This will simply raise the KeyError set by PyDict_DelItem
500 if the file descriptor isn't registered. */
501 return NULL;
502 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 Py_DECREF(key);
505 self->ufd_uptodate = 0;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 Py_INCREF(Py_None);
508 return Py_None;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000509}
510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000511PyDoc_STRVAR(poll_poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000512"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
513Polls the set of registered file descriptors, returning a list containing \n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000514any descriptors that have events or errors to report.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000515
516static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517poll_poll(pollObject *self, PyObject *args)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 PyObject *result_list = NULL, *tout = NULL;
520 int timeout = 0, poll_result, i, j;
521 PyObject *value = NULL, *num = NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
524 return NULL;
525 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 /* Check values for timeout */
528 if (tout == NULL || tout == Py_None)
529 timeout = -1;
530 else if (!PyNumber_Check(tout)) {
531 PyErr_SetString(PyExc_TypeError,
532 "timeout must be an integer or None");
533 return NULL;
534 }
535 else {
536 tout = PyNumber_Long(tout);
537 if (!tout)
538 return NULL;
Serhiy Storchaka78980432013-01-15 01:12:17 +0200539 timeout = _PyLong_AsInt(tout);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 Py_DECREF(tout);
541 if (timeout == -1 && PyErr_Occurred())
542 return NULL;
543 }
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000544
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300545 /* Avoid concurrent poll() invocation, issue 8865 */
546 if (self->poll_running) {
547 PyErr_SetString(PyExc_RuntimeError,
548 "concurrent poll() invocation");
549 return NULL;
550 }
551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 /* Ensure the ufd array is up to date */
553 if (!self->ufd_uptodate)
554 if (update_ufd_array(self) == 0)
555 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000556
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300557 self->poll_running = 1;
558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 /* call poll() */
560 Py_BEGIN_ALLOW_THREADS
561 poll_result = poll(self->ufds, self->ufd_len, timeout);
562 Py_END_ALLOW_THREADS
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000563
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300564 self->poll_running = 0;
565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 if (poll_result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200567 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 return NULL;
569 }
570
571 /* build the result list */
572
573 result_list = PyList_New(poll_result);
574 if (!result_list)
575 return NULL;
576 else {
577 for (i = 0, j = 0; j < poll_result; j++) {
578 /* skip to the next fired descriptor */
579 while (!self->ufds[i].revents) {
580 i++;
581 }
582 /* if we hit a NULL return, set value to NULL
583 and break out of loop; code at end will
584 clean up result_list */
585 value = PyTuple_New(2);
586 if (value == NULL)
587 goto error;
588 num = PyLong_FromLong(self->ufds[i].fd);
589 if (num == NULL) {
590 Py_DECREF(value);
591 goto error;
592 }
593 PyTuple_SET_ITEM(value, 0, num);
594
595 /* The &0xffff is a workaround for AIX. 'revents'
596 is a 16-bit short, and IBM assigned POLLNVAL
597 to be 0x8000, so the conversion to int results
598 in a negative number. See SF bug #923315. */
599 num = PyLong_FromLong(self->ufds[i].revents & 0xffff);
600 if (num == NULL) {
601 Py_DECREF(value);
602 goto error;
603 }
604 PyTuple_SET_ITEM(value, 1, num);
605 if ((PyList_SetItem(result_list, j, value)) == -1) {
606 Py_DECREF(value);
607 goto error;
608 }
609 i++;
610 }
611 }
612 return result_list;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000613
614 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 Py_DECREF(result_list);
616 return NULL;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000617}
618
619static PyMethodDef poll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 {"register", (PyCFunction)poll_register,
621 METH_VARARGS, poll_register_doc},
622 {"modify", (PyCFunction)poll_modify,
623 METH_VARARGS, poll_modify_doc},
624 {"unregister", (PyCFunction)poll_unregister,
625 METH_O, poll_unregister_doc},
626 {"poll", (PyCFunction)poll_poll,
627 METH_VARARGS, poll_poll_doc},
628 {NULL, NULL} /* sentinel */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000629};
630
631static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000632newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 pollObject *self;
635 self = PyObject_New(pollObject, &poll_Type);
636 if (self == NULL)
637 return NULL;
638 /* ufd_uptodate is a Boolean, denoting whether the
639 array pointed to by ufds matches the contents of the dictionary. */
640 self->ufd_uptodate = 0;
641 self->ufds = NULL;
Serhiy Storchakab1973c22013-08-20 20:38:21 +0300642 self->poll_running = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 self->dict = PyDict_New();
644 if (self->dict == NULL) {
645 Py_DECREF(self);
646 return NULL;
647 }
648 return self;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000649}
650
651static void
652poll_dealloc(pollObject *self)
653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 if (self->ufds != NULL)
655 PyMem_DEL(self->ufds);
656 Py_XDECREF(self->dict);
657 PyObject_Del(self);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000658}
659
Tim Peters0c322792002-07-17 16:49:03 +0000660static PyTypeObject poll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 /* The ob_type field must be initialized in the module init function
662 * to be portable to Windows without using C++. */
663 PyVarObject_HEAD_INIT(NULL, 0)
664 "select.poll", /*tp_name*/
665 sizeof(pollObject), /*tp_basicsize*/
666 0, /*tp_itemsize*/
667 /* methods */
668 (destructor)poll_dealloc, /*tp_dealloc*/
669 0, /*tp_print*/
670 0, /*tp_getattr*/
671 0, /*tp_setattr*/
672 0, /*tp_reserved*/
673 0, /*tp_repr*/
674 0, /*tp_as_number*/
675 0, /*tp_as_sequence*/
676 0, /*tp_as_mapping*/
677 0, /*tp_hash*/
678 0, /*tp_call*/
679 0, /*tp_str*/
680 0, /*tp_getattro*/
681 0, /*tp_setattro*/
682 0, /*tp_as_buffer*/
683 Py_TPFLAGS_DEFAULT, /*tp_flags*/
684 0, /*tp_doc*/
685 0, /*tp_traverse*/
686 0, /*tp_clear*/
687 0, /*tp_richcompare*/
688 0, /*tp_weaklistoffset*/
689 0, /*tp_iter*/
690 0, /*tp_iternext*/
691 poll_methods, /*tp_methods*/
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000692};
693
Jesus Cead8b9ae62011-11-14 19:07:41 +0100694#ifdef HAVE_SYS_DEVPOLL_H
695typedef struct {
696 PyObject_HEAD
697 int fd_devpoll;
698 int max_n_fds;
699 int n_fds;
700 struct pollfd *fds;
701} devpollObject;
702
703static PyTypeObject devpoll_Type;
704
Victor Stinner13423c32013-08-22 00:19:50 +0200705static PyObject *
706devpoll_err_closed(void)
707{
708 PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object");
709 return NULL;
710}
711
Jesus Cead8b9ae62011-11-14 19:07:41 +0100712static int devpoll_flush(devpollObject *self)
713{
714 int size, n;
715
716 if (!self->n_fds) return 0;
717
718 size = sizeof(struct pollfd)*self->n_fds;
719 self->n_fds = 0;
720
721 Py_BEGIN_ALLOW_THREADS
722 n = write(self->fd_devpoll, self->fds, size);
723 Py_END_ALLOW_THREADS
724
725 if (n == -1 ) {
726 PyErr_SetFromErrno(PyExc_IOError);
727 return -1;
728 }
729 if (n < size) {
730 /*
731 ** Data writed to /dev/poll is a binary data structure. It is not
732 ** clear what to do if a partial write occurred. For now, raise
733 ** an exception and see if we actually found this problem in
734 ** the wild.
735 ** See http://bugs.python.org/issue6397.
736 */
737 PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
738 "Please, report at http://bugs.python.org/. "
739 "Data to report: Size tried: %d, actual size written: %d.",
740 size, n);
741 return -1;
742 }
743 return 0;
744}
745
746static PyObject *
747internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
748{
749 PyObject *o;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200750 int fd;
751 unsigned short events = POLLIN | POLLPRI | POLLOUT;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100752
Victor Stinner13423c32013-08-22 00:19:50 +0200753 if (self->fd_devpoll < 0)
754 return devpoll_err_closed();
755
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200756 if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
Jesus Cead8b9ae62011-11-14 19:07:41 +0100757 return NULL;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100758
759 fd = PyObject_AsFileDescriptor(o);
760 if (fd == -1) return NULL;
761
762 if (remove) {
763 self->fds[self->n_fds].fd = fd;
764 self->fds[self->n_fds].events = POLLREMOVE;
765
766 if (++self->n_fds == self->max_n_fds) {
767 if (devpoll_flush(self))
768 return NULL;
769 }
770 }
771
772 self->fds[self->n_fds].fd = fd;
Serhiy Storchaka5da107a2013-12-14 19:12:02 +0200773 self->fds[self->n_fds].events = (signed short)events;
Jesus Cead8b9ae62011-11-14 19:07:41 +0100774
775 if (++self->n_fds == self->max_n_fds) {
776 if (devpoll_flush(self))
777 return NULL;
778 }
779
780 Py_RETURN_NONE;
781}
782
783PyDoc_STRVAR(devpoll_register_doc,
784"register(fd [, eventmask] ) -> None\n\n\
785Register a file descriptor with the polling object.\n\
786fd -- either an integer, or an object with a fileno() method returning an\n\
787 int.\n\
788events -- an optional bitmask describing the type of events to check for");
789
790static PyObject *
791devpoll_register(devpollObject *self, PyObject *args)
792{
793 return internal_devpoll_register(self, args, 0);
794}
795
796PyDoc_STRVAR(devpoll_modify_doc,
797"modify(fd[, eventmask]) -> None\n\n\
798Modify a possible already registered file descriptor.\n\
799fd -- either an integer, or an object with a fileno() method returning an\n\
800 int.\n\
801events -- an optional bitmask describing the type of events to check for");
802
803static PyObject *
804devpoll_modify(devpollObject *self, PyObject *args)
805{
806 return internal_devpoll_register(self, args, 1);
807}
808
809
810PyDoc_STRVAR(devpoll_unregister_doc,
811"unregister(fd) -> None\n\n\
812Remove a file descriptor being tracked by the polling object.");
813
814static PyObject *
815devpoll_unregister(devpollObject *self, PyObject *o)
816{
817 int fd;
818
Victor Stinner13423c32013-08-22 00:19:50 +0200819 if (self->fd_devpoll < 0)
820 return devpoll_err_closed();
821
Jesus Cead8b9ae62011-11-14 19:07:41 +0100822 fd = PyObject_AsFileDescriptor( o );
823 if (fd == -1)
824 return NULL;
825
826 self->fds[self->n_fds].fd = fd;
827 self->fds[self->n_fds].events = POLLREMOVE;
828
829 if (++self->n_fds == self->max_n_fds) {
830 if (devpoll_flush(self))
831 return NULL;
832 }
833
834 Py_RETURN_NONE;
835}
836
837PyDoc_STRVAR(devpoll_poll_doc,
838"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
839Polls the set of registered file descriptors, returning a list containing \n\
840any descriptors that have events or errors to report.");
841
842static PyObject *
843devpoll_poll(devpollObject *self, PyObject *args)
844{
845 struct dvpoll dvp;
846 PyObject *result_list = NULL, *tout = NULL;
847 int poll_result, i;
848 long timeout;
849 PyObject *value, *num1, *num2;
850
Victor Stinner13423c32013-08-22 00:19:50 +0200851 if (self->fd_devpoll < 0)
852 return devpoll_err_closed();
853
Jesus Cead8b9ae62011-11-14 19:07:41 +0100854 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
855 return NULL;
856 }
857
858 /* Check values for timeout */
859 if (tout == NULL || tout == Py_None)
860 timeout = -1;
861 else if (!PyNumber_Check(tout)) {
862 PyErr_SetString(PyExc_TypeError,
863 "timeout must be an integer or None");
864 return NULL;
865 }
866 else {
867 tout = PyNumber_Long(tout);
868 if (!tout)
869 return NULL;
870 timeout = PyLong_AsLong(tout);
871 Py_DECREF(tout);
872 if (timeout == -1 && PyErr_Occurred())
873 return NULL;
874 }
875
876 if ((timeout < -1) || (timeout > INT_MAX)) {
877 PyErr_SetString(PyExc_OverflowError,
878 "timeout is out of range");
879 return NULL;
880 }
881
882 if (devpoll_flush(self))
883 return NULL;
884
885 dvp.dp_fds = self->fds;
886 dvp.dp_nfds = self->max_n_fds;
887 dvp.dp_timeout = timeout;
888
889 /* call devpoll() */
890 Py_BEGIN_ALLOW_THREADS
891 poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
892 Py_END_ALLOW_THREADS
893
894 if (poll_result < 0) {
895 PyErr_SetFromErrno(PyExc_IOError);
896 return NULL;
897 }
898
899 /* build the result list */
900
901 result_list = PyList_New(poll_result);
902 if (!result_list)
903 return NULL;
904 else {
905 for (i = 0; i < poll_result; i++) {
906 num1 = PyLong_FromLong(self->fds[i].fd);
907 num2 = PyLong_FromLong(self->fds[i].revents);
908 if ((num1 == NULL) || (num2 == NULL)) {
909 Py_XDECREF(num1);
910 Py_XDECREF(num2);
911 goto error;
912 }
913 value = PyTuple_Pack(2, num1, num2);
914 Py_DECREF(num1);
915 Py_DECREF(num2);
916 if (value == NULL)
917 goto error;
918 if ((PyList_SetItem(result_list, i, value)) == -1) {
919 Py_DECREF(value);
920 goto error;
921 }
922 }
923 }
924
925 return result_list;
926
927 error:
928 Py_DECREF(result_list);
929 return NULL;
930}
931
Richard Oudkerk168d59b2013-08-22 13:31:15 +0100932static int
933devpoll_internal_close(devpollObject *self)
934{
935 int save_errno = 0;
936 if (self->fd_devpoll >= 0) {
937 int fd = self->fd_devpoll;
938 self->fd_devpoll = -1;
939 Py_BEGIN_ALLOW_THREADS
940 if (close(fd) < 0)
941 save_errno = errno;
942 Py_END_ALLOW_THREADS
943 }
944 return save_errno;
945}
946
Victor Stinner13423c32013-08-22 00:19:50 +0200947static PyObject*
948devpoll_close(devpollObject *self)
949{
950 errno = devpoll_internal_close(self);
951 if (errno < 0) {
952 PyErr_SetFromErrno(PyExc_OSError);
953 return NULL;
954 }
955 Py_RETURN_NONE;
956}
957
958PyDoc_STRVAR(devpoll_close_doc,
959"close() -> None\n\
960\n\
961Close the devpoll file descriptor. Further operations on the devpoll\n\
962object will raise an exception.");
963
964static PyObject*
965devpoll_get_closed(devpollObject *self)
966{
967 if (self->fd_devpoll < 0)
968 Py_RETURN_TRUE;
969 else
970 Py_RETURN_FALSE;
971}
972
973static PyObject*
974devpoll_fileno(devpollObject *self)
975{
976 if (self->fd_devpoll < 0)
977 return devpoll_err_closed();
978 return PyLong_FromLong(self->fd_devpoll);
979}
980
981PyDoc_STRVAR(devpoll_fileno_doc,
982"fileno() -> int\n\
983\n\
984Return the file descriptor.");
985
Jesus Cead8b9ae62011-11-14 19:07:41 +0100986static PyMethodDef devpoll_methods[] = {
987 {"register", (PyCFunction)devpoll_register,
988 METH_VARARGS, devpoll_register_doc},
989 {"modify", (PyCFunction)devpoll_modify,
990 METH_VARARGS, devpoll_modify_doc},
991 {"unregister", (PyCFunction)devpoll_unregister,
992 METH_O, devpoll_unregister_doc},
993 {"poll", (PyCFunction)devpoll_poll,
994 METH_VARARGS, devpoll_poll_doc},
Victor Stinner13423c32013-08-22 00:19:50 +0200995 {"close", (PyCFunction)devpoll_close, METH_NOARGS,
996 devpoll_close_doc},
997 {"fileno", (PyCFunction)devpoll_fileno, METH_NOARGS,
998 devpoll_fileno_doc},
Jesus Cead8b9ae62011-11-14 19:07:41 +0100999 {NULL, NULL} /* sentinel */
1000};
1001
Victor Stinner13423c32013-08-22 00:19:50 +02001002static PyGetSetDef devpoll_getsetlist[] = {
1003 {"closed", (getter)devpoll_get_closed, NULL,
1004 "True if the devpoll object is closed"},
1005 {0},
1006};
1007
Jesus Cead8b9ae62011-11-14 19:07:41 +01001008static devpollObject *
1009newDevPollObject(void)
1010{
1011 devpollObject *self;
1012 int fd_devpoll, limit_result;
1013 struct pollfd *fds;
1014 struct rlimit limit;
1015
1016 Py_BEGIN_ALLOW_THREADS
1017 /*
1018 ** If we try to process more that getrlimit()
1019 ** fds, the kernel will give an error, so
1020 ** we set the limit here. It is a dynamic
1021 ** value, because we can change rlimit() anytime.
1022 */
1023 limit_result = getrlimit(RLIMIT_NOFILE, &limit);
1024 if (limit_result != -1)
Victor Stinnerdaf45552013-08-28 00:53:59 +02001025 fd_devpoll = _Py_open("/dev/poll", O_RDWR);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001026 Py_END_ALLOW_THREADS
1027
1028 if (limit_result == -1) {
1029 PyErr_SetFromErrno(PyExc_OSError);
1030 return NULL;
1031 }
1032 if (fd_devpoll == -1) {
1033 PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
1034 return NULL;
1035 }
1036
1037 fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
1038 if (fds == NULL) {
1039 close(fd_devpoll);
1040 PyErr_NoMemory();
1041 return NULL;
1042 }
1043
1044 self = PyObject_New(devpollObject, &devpoll_Type);
1045 if (self == NULL) {
1046 close(fd_devpoll);
1047 PyMem_DEL(fds);
1048 return NULL;
1049 }
1050 self->fd_devpoll = fd_devpoll;
1051 self->max_n_fds = limit.rlim_cur;
1052 self->n_fds = 0;
1053 self->fds = fds;
1054
1055 return self;
1056}
1057
1058static void
1059devpoll_dealloc(devpollObject *self)
1060{
Richard Oudkerka93bf7b2013-08-22 14:03:44 +01001061 (void)devpoll_internal_close(self);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001062 PyMem_DEL(self->fds);
Jesus Cead8b9ae62011-11-14 19:07:41 +01001063 PyObject_Del(self);
1064}
1065
1066static PyTypeObject devpoll_Type = {
1067 /* The ob_type field must be initialized in the module init function
1068 * to be portable to Windows without using C++. */
1069 PyVarObject_HEAD_INIT(NULL, 0)
1070 "select.devpoll", /*tp_name*/
1071 sizeof(devpollObject), /*tp_basicsize*/
1072 0, /*tp_itemsize*/
1073 /* methods */
1074 (destructor)devpoll_dealloc, /*tp_dealloc*/
1075 0, /*tp_print*/
1076 0, /*tp_getattr*/
1077 0, /*tp_setattr*/
1078 0, /*tp_reserved*/
1079 0, /*tp_repr*/
1080 0, /*tp_as_number*/
1081 0, /*tp_as_sequence*/
1082 0, /*tp_as_mapping*/
1083 0, /*tp_hash*/
1084 0, /*tp_call*/
1085 0, /*tp_str*/
1086 0, /*tp_getattro*/
1087 0, /*tp_setattro*/
1088 0, /*tp_as_buffer*/
1089 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1090 0, /*tp_doc*/
1091 0, /*tp_traverse*/
1092 0, /*tp_clear*/
1093 0, /*tp_richcompare*/
1094 0, /*tp_weaklistoffset*/
1095 0, /*tp_iter*/
1096 0, /*tp_iternext*/
1097 devpoll_methods, /*tp_methods*/
Victor Stinner13423c32013-08-22 00:19:50 +02001098 0, /* tp_members */
1099 devpoll_getsetlist, /* tp_getset */
Jesus Cead8b9ae62011-11-14 19:07:41 +01001100};
1101#endif /* HAVE_SYS_DEVPOLL_H */
1102
1103
1104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001105PyDoc_STRVAR(poll_doc,
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001106"Returns a polling object, which supports registering and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001107unregistering file descriptors, and then polling them for I/O events.");
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001108
1109static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001110select_poll(PyObject *self, PyObject *unused)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 return (PyObject *)newPollObject();
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001113}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001114
Jesus Cead8b9ae62011-11-14 19:07:41 +01001115#ifdef HAVE_SYS_DEVPOLL_H
1116PyDoc_STRVAR(devpoll_doc,
1117"Returns a polling object, which supports registering and\n\
1118unregistering file descriptors, and then polling them for I/O events.");
1119
1120static PyObject *
1121select_devpoll(PyObject *self, PyObject *unused)
1122{
1123 return (PyObject *)newDevPollObject();
1124}
1125#endif
1126
1127
Thomas Wouters477c8d52006-05-27 19:21:47 +00001128#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129/*
Thomas Wouters477c8d52006-05-27 19:21:47 +00001130 * On some systems poll() sets errno on invalid file descriptors. We test
1131 * for this at runtime because this bug may be fixed or introduced between
1132 * OS releases.
1133 */
1134static int select_have_broken_poll(void)
1135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 int poll_test;
1137 int filedes[2];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
Thomas Wouters477c8d52006-05-27 19:21:47 +00001140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 /* Create a file descriptor to make invalid */
1142 if (pipe(filedes) < 0) {
1143 return 1;
1144 }
1145 poll_struct.fd = filedes[0];
1146 close(filedes[0]);
1147 close(filedes[1]);
1148 poll_test = poll(&poll_struct, 1, 0);
1149 if (poll_test < 0) {
1150 return 1;
1151 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
1152 return 1;
1153 }
1154 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001155}
1156#endif /* __APPLE__ */
1157
1158#endif /* HAVE_POLL */
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00001159
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001160#ifdef HAVE_EPOLL
1161/* **************************************************************************
1162 * epoll interface for Linux 2.6
1163 *
1164 * Written by Christian Heimes
1165 * Inspired by Twisted's _epoll.pyx and select.poll()
1166 */
1167
1168#ifdef HAVE_SYS_EPOLL_H
1169#include <sys/epoll.h>
1170#endif
1171
1172typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 PyObject_HEAD
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001174 SOCKET epfd; /* epoll control file descriptor */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001175} pyEpoll_Object;
1176
1177static PyTypeObject pyEpoll_Type;
1178#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
1179
1180static PyObject *
1181pyepoll_err_closed(void)
1182{
Victor Stinner13423c32013-08-22 00:19:50 +02001183 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001185}
1186
1187static int
1188pyepoll_internal_close(pyEpoll_Object *self)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 int save_errno = 0;
1191 if (self->epfd >= 0) {
1192 int epfd = self->epfd;
1193 self->epfd = -1;
1194 Py_BEGIN_ALLOW_THREADS
1195 if (close(epfd) < 0)
1196 save_errno = errno;
1197 Py_END_ALLOW_THREADS
1198 }
1199 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001200}
1201
1202static PyObject *
Benjamin Peterson95c16622011-12-27 15:36:32 -06001203newPyEpoll_Object(PyTypeObject *type, int sizehint, int flags, SOCKET fd)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 pyEpoll_Object *self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 assert(type != NULL && type->tp_alloc != NULL);
1208 self = (pyEpoll_Object *) type->tp_alloc(type, 0);
1209 if (self == NULL)
1210 return NULL;
1211
1212 if (fd == -1) {
1213 Py_BEGIN_ALLOW_THREADS
Benjamin Peterson95c16622011-12-27 15:36:32 -06001214#ifdef HAVE_EPOLL_CREATE1
Victor Stinnerdaf45552013-08-28 00:53:59 +02001215 flags |= EPOLL_CLOEXEC;
Benjamin Peterson83251c12011-12-27 16:01:21 -06001216 if (flags)
1217 self->epfd = epoll_create1(flags);
1218 else
Benjamin Peterson95c16622011-12-27 15:36:32 -06001219#endif
Benjamin Peterson83251c12011-12-27 16:01:21 -06001220 self->epfd = epoll_create(sizehint);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 Py_END_ALLOW_THREADS
1222 }
1223 else {
1224 self->epfd = fd;
1225 }
1226 if (self->epfd < 0) {
1227 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001228 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 return NULL;
1230 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001231
1232#ifndef HAVE_EPOLL_CREATE1
Victor Stinnerd72fe892013-08-28 12:22:39 +02001233 if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) {
Victor Stinnerdaf45552013-08-28 00:53:59 +02001234 Py_DECREF(self);
1235 return NULL;
1236 }
1237#endif
1238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001240}
1241
1242
1243static PyObject *
1244pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1245{
Benjamin Peterson83251c12011-12-27 16:01:21 -06001246 int flags = 0, sizehint = FD_SETSIZE - 1;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001247 static char *kwlist[] = {"sizehint", "flags", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001248
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001249 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:epoll", kwlist,
1250 &sizehint, &flags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return NULL;
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001252 if (sizehint < 0) {
1253 PyErr_SetString(PyExc_ValueError, "negative sizehint");
1254 return NULL;
1255 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001256
Benjamin Peterson95c16622011-12-27 15:36:32 -06001257 return newPyEpoll_Object(type, sizehint, flags, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001258}
1259
1260
1261static void
1262pyepoll_dealloc(pyEpoll_Object *self)
1263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 (void)pyepoll_internal_close(self);
1265 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001266}
1267
1268static PyObject*
1269pyepoll_close(pyEpoll_Object *self)
1270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 errno = pyepoll_internal_close(self);
1272 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001273 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 return NULL;
1275 }
1276 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001277}
1278
1279PyDoc_STRVAR(pyepoll_close_doc,
1280"close() -> None\n\
1281\n\
1282Close the epoll control file descriptor. Further operations on the epoll\n\
1283object will raise an exception.");
1284
1285static PyObject*
1286pyepoll_get_closed(pyEpoll_Object *self)
1287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (self->epfd < 0)
1289 Py_RETURN_TRUE;
1290 else
1291 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001292}
1293
1294static PyObject*
1295pyepoll_fileno(pyEpoll_Object *self)
1296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 if (self->epfd < 0)
1298 return pyepoll_err_closed();
1299 return PyLong_FromLong(self->epfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001300}
1301
1302PyDoc_STRVAR(pyepoll_fileno_doc,
1303"fileno() -> int\n\
1304\n\
1305Return the epoll control file descriptor.");
1306
1307static PyObject*
1308pyepoll_fromfd(PyObject *cls, PyObject *args)
1309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
1313 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001314
Benjamin Peterson95c16622011-12-27 15:36:32 -06001315 return newPyEpoll_Object((PyTypeObject*)cls, FD_SETSIZE - 1, 0, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001316}
1317
1318PyDoc_STRVAR(pyepoll_fromfd_doc,
1319"fromfd(fd) -> epoll\n\
1320\n\
1321Create an epoll object from a given control fd.");
1322
1323static PyObject *
1324pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
1325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 struct epoll_event ev;
1327 int result;
1328 int fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 if (epfd < 0)
1331 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 fd = PyObject_AsFileDescriptor(pfd);
1334 if (fd == -1) {
1335 return NULL;
1336 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001337
Guido van Rossumee07b942013-12-06 17:46:22 -08001338 switch (op) {
1339 case EPOLL_CTL_ADD:
1340 case EPOLL_CTL_MOD:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 ev.events = events;
1342 ev.data.fd = fd;
1343 Py_BEGIN_ALLOW_THREADS
1344 result = epoll_ctl(epfd, op, fd, &ev);
1345 Py_END_ALLOW_THREADS
1346 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001347 case EPOLL_CTL_DEL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
1349 * operation required a non-NULL pointer in event, even
1350 * though this argument is ignored. */
1351 Py_BEGIN_ALLOW_THREADS
1352 result = epoll_ctl(epfd, op, fd, &ev);
1353 if (errno == EBADF) {
1354 /* fd already closed */
1355 result = 0;
1356 errno = 0;
1357 }
1358 Py_END_ALLOW_THREADS
1359 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001360 default:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 result = -1;
1362 errno = EINVAL;
1363 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 if (result < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001366 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 return NULL;
1368 }
1369 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001370}
1371
1372static PyObject *
1373pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject *pfd;
1376 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
1377 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
1380 &pfd, &events)) {
1381 return NULL;
1382 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001385}
1386
1387PyDoc_STRVAR(pyepoll_register_doc,
Georg Brandl222569d2010-08-02 20:47:56 +00001388"register(fd[, eventmask]) -> None\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001389\n\
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001390Registers a new fd or raises an OSError if the fd is already registered.\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00001391fd is the target file descriptor of the operation.\n\
1392events is a bit set composed of the various EPOLL constants; the default\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001393is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
1394\n\
1395The epoll interface supports all file descriptors that support poll.");
1396
1397static PyObject *
1398pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 PyObject *pfd;
1401 unsigned int events;
1402 static char *kwlist[] = {"fd", "eventmask", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
1405 &pfd, &events)) {
1406 return NULL;
1407 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001410}
1411
1412PyDoc_STRVAR(pyepoll_modify_doc,
1413"modify(fd, eventmask) -> None\n\
1414\n\
1415fd is the target file descriptor of the operation\n\
1416events is a bit set composed of the various EPOLL constants");
1417
1418static PyObject *
1419pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 PyObject *pfd;
1422 static char *kwlist[] = {"fd", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
1425 &pfd)) {
1426 return NULL;
1427 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001430}
1431
1432PyDoc_STRVAR(pyepoll_unregister_doc,
1433"unregister(fd) -> None\n\
1434\n\
1435fd is the target file descriptor of the operation.");
1436
1437static PyObject *
1438pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
1439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 double dtimeout = -1.;
1441 int timeout;
1442 int maxevents = -1;
1443 int nfds, i;
1444 PyObject *elist = NULL, *etuple = NULL;
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001445 struct epoll_event *evs = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 static char *kwlist[] = {"timeout", "maxevents", NULL};
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 if (self->epfd < 0)
1449 return pyepoll_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
1452 &dtimeout, &maxevents)) {
1453 return NULL;
1454 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 if (dtimeout < 0) {
1457 timeout = -1;
1458 }
1459 else if (dtimeout * 1000.0 > INT_MAX) {
1460 PyErr_SetString(PyExc_OverflowError,
1461 "timeout is too large");
1462 return NULL;
1463 }
1464 else {
Victor Stinnerdcd97402014-01-31 12:12:53 +01001465 /* epoll_wait() has a resolution of 1 millisecond, round away from zero
1466 to wait *at least* dtimeout seconds. */
1467 timeout = (int)ceil(dtimeout * 1000.0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 if (maxevents == -1) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001471 maxevents = FD_SETSIZE-1;
1472 }
1473 else if (maxevents < 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 PyErr_Format(PyExc_ValueError,
1475 "maxevents must be greater than 0, got %d",
1476 maxevents);
1477 return NULL;
1478 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001479
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001480 evs = PyMem_New(struct epoll_event, maxevents);
1481 if (evs == NULL) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001482 PyErr_NoMemory();
1483 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 Py_BEGIN_ALLOW_THREADS
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001487 nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 Py_END_ALLOW_THREADS
1489 if (nfds < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001490 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 goto error;
1492 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 elist = PyList_New(nfds);
1495 if (elist == NULL) {
1496 goto error;
1497 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 for (i = 0; i < nfds; i++) {
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001500 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (etuple == NULL) {
1502 Py_CLEAR(elist);
1503 goto error;
1504 }
1505 PyList_SET_ITEM(elist, i, etuple);
1506 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001507
Christian Heimesf6cd9672008-03-26 13:45:42 +00001508 error:
Charles-François Natalia6ebb2d2013-01-12 12:31:00 +01001509 PyMem_Free(evs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 return elist;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001511}
1512
1513PyDoc_STRVAR(pyepoll_poll_doc,
1514"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
1515\n\
1516Wait for events on the epoll file descriptor for a maximum time of timeout\n\
1517in seconds (as float). -1 makes poll wait indefinitely.\n\
1518Up to maxevents are returned to the caller.");
1519
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001520static PyObject *
1521pyepoll_enter(pyEpoll_Object *self, PyObject *args)
1522{
1523 if (self->epfd < 0)
1524 return pyepoll_err_closed();
1525
1526 Py_INCREF(self);
1527 return (PyObject *)self;
1528}
1529
1530static PyObject *
1531pyepoll_exit(PyObject *self, PyObject *args)
1532{
1533 _Py_IDENTIFIER(close);
1534
1535 return _PyObject_CallMethodId(self, &PyId_close, NULL);
1536}
1537
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001538static PyMethodDef pyepoll_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 {"fromfd", (PyCFunction)pyepoll_fromfd,
1540 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
1541 {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
1542 pyepoll_close_doc},
1543 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
1544 pyepoll_fileno_doc},
1545 {"modify", (PyCFunction)pyepoll_modify,
1546 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
1547 {"register", (PyCFunction)pyepoll_register,
1548 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
1549 {"unregister", (PyCFunction)pyepoll_unregister,
1550 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
1551 {"poll", (PyCFunction)pyepoll_poll,
1552 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
Antoine Pitrou09bb89b2012-12-15 21:14:21 +01001553 {"__enter__", (PyCFunction)pyepoll_enter, METH_NOARGS,
1554 NULL},
1555 {"__exit__", (PyCFunction)pyepoll_exit, METH_VARARGS,
1556 NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001558};
1559
1560static PyGetSetDef pyepoll_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 {"closed", (getter)pyepoll_get_closed, NULL,
1562 "True if the epoll handler is closed"},
1563 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001564};
1565
1566PyDoc_STRVAR(pyepoll_doc,
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06001567"select.epoll(sizehint=-1, flags=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001568\n\
1569Returns an epolling object\n\
1570\n\
1571sizehint must be a positive integer or -1 for the default size. The\n\
1572sizehint is used to optimize internal data structures. It doesn't limit\n\
1573the maximum number of monitored events.");
1574
1575static PyTypeObject pyEpoll_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 PyVarObject_HEAD_INIT(NULL, 0)
1577 "select.epoll", /* tp_name */
1578 sizeof(pyEpoll_Object), /* tp_basicsize */
1579 0, /* tp_itemsize */
1580 (destructor)pyepoll_dealloc, /* tp_dealloc */
1581 0, /* tp_print */
1582 0, /* tp_getattr */
1583 0, /* tp_setattr */
1584 0, /* tp_reserved */
1585 0, /* tp_repr */
1586 0, /* tp_as_number */
1587 0, /* tp_as_sequence */
1588 0, /* tp_as_mapping */
1589 0, /* tp_hash */
1590 0, /* tp_call */
1591 0, /* tp_str */
1592 PyObject_GenericGetAttr, /* tp_getattro */
1593 0, /* tp_setattro */
1594 0, /* tp_as_buffer */
1595 Py_TPFLAGS_DEFAULT, /* tp_flags */
1596 pyepoll_doc, /* tp_doc */
1597 0, /* tp_traverse */
1598 0, /* tp_clear */
1599 0, /* tp_richcompare */
1600 0, /* tp_weaklistoffset */
1601 0, /* tp_iter */
1602 0, /* tp_iternext */
1603 pyepoll_methods, /* tp_methods */
1604 0, /* tp_members */
1605 pyepoll_getsetlist, /* tp_getset */
1606 0, /* tp_base */
1607 0, /* tp_dict */
1608 0, /* tp_descr_get */
1609 0, /* tp_descr_set */
1610 0, /* tp_dictoffset */
1611 0, /* tp_init */
1612 0, /* tp_alloc */
1613 pyepoll_new, /* tp_new */
1614 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001615};
1616
1617#endif /* HAVE_EPOLL */
1618
1619#ifdef HAVE_KQUEUE
1620/* **************************************************************************
1621 * kqueue interface for BSD
1622 *
1623 * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
1624 * All rights reserved.
1625 *
1626 * Redistribution and use in source and binary forms, with or without
1627 * modification, are permitted provided that the following conditions
1628 * are met:
1629 * 1. Redistributions of source code must retain the above copyright
1630 * notice, this list of conditions and the following disclaimer.
1631 * 2. Redistributions in binary form must reproduce the above copyright
1632 * notice, this list of conditions and the following disclaimer in the
1633 * documentation and/or other materials provided with the distribution.
1634 *
1635 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1636 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1637 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1638 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1639 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1640 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1641 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1642 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1643 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1644 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1645 * SUCH DAMAGE.
1646 */
1647
1648#ifdef HAVE_SYS_EVENT_H
1649#include <sys/event.h>
1650#endif
1651
1652PyDoc_STRVAR(kqueue_event_doc,
Benjamin Peterson1baf4652009-12-31 03:11:23 +00001653"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001654\n\
1655This object is the equivalent of the struct kevent for the C API.\n\
1656\n\
1657See the kqueue manpage for more detailed information about the meaning\n\
1658of the arguments.\n\
1659\n\
1660One minor note: while you might hope that udata could store a\n\
1661reference to a python object, it cannot, because it is impossible to\n\
1662keep a proper reference count of the object once it's passed into the\n\
1663kernel. Therefore, I have restricted it to only storing an integer. I\n\
1664recommend ignoring it and simply using the 'ident' field to key off\n\
1665of. You could also set up a dictionary on the python side to store a\n\
1666udata->object mapping.");
1667
1668typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 PyObject_HEAD
1670 struct kevent e;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001671} kqueue_event_Object;
1672
1673static PyTypeObject kqueue_event_Type;
1674
1675#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
1676
1677typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 PyObject_HEAD
1679 SOCKET kqfd; /* kqueue control fd */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001680} kqueue_queue_Object;
1681
1682static PyTypeObject kqueue_queue_Type;
1683
1684#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
1685
Antoine Pitroud83f1e62009-11-04 21:10:38 +00001686#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
1687# error uintptr_t does not match void *!
1688#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
1689# define T_UINTPTRT T_ULONGLONG
1690# define T_INTPTRT T_LONGLONG
1691# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
1692# define UINTPTRT_FMT_UNIT "K"
1693# define INTPTRT_FMT_UNIT "L"
1694#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
1695# define T_UINTPTRT T_ULONG
1696# define T_INTPTRT T_LONG
1697# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1698# define UINTPTRT_FMT_UNIT "k"
1699# define INTPTRT_FMT_UNIT "l"
1700#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
1701# define T_UINTPTRT T_UINT
1702# define T_INTPTRT T_INT
1703# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
1704# define UINTPTRT_FMT_UNIT "I"
1705# define INTPTRT_FMT_UNIT "i"
1706#else
1707# error uintptr_t does not match int, long, or long long!
1708#endif
1709
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001710/*
1711 * kevent is not standard and its members vary across BSDs.
1712 */
1713#if !defined(__OpenBSD__)
Christian Heimesaf01f662013-12-21 16:19:10 +01001714# define IDENT_TYPE T_UINTPTRT
1715# define IDENT_CAST Py_intptr_t
1716# define DATA_TYPE T_INTPTRT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001717# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
Christian Heimesaf01f662013-12-21 16:19:10 +01001718# define IDENT_AsType PyLong_AsUintptr_t
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001719#else
Christian Heimesaf01f662013-12-21 16:19:10 +01001720# define IDENT_TYPE T_UINT
1721# define IDENT_CAST int
1722# define DATA_TYPE T_INT
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001723# define DATA_FMT_UNIT "i"
Christian Heimesaf01f662013-12-21 16:19:10 +01001724# define IDENT_AsType PyLong_AsUnsignedLong
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001725#endif
1726
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001727/* Unfortunately, we can't store python objects in udata, because
1728 * kevents in the kernel can be removed without warning, which would
1729 * forever lose the refcount on the object stored with it.
1730 */
1731
1732#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
1733static struct PyMemberDef kqueue_event_members[] = {
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001734 {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 {"filter", T_SHORT, KQ_OFF(e.filter)},
1736 {"flags", T_USHORT, KQ_OFF(e.flags)},
1737 {"fflags", T_UINT, KQ_OFF(e.fflags)},
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001738 {"data", DATA_TYPE, KQ_OFF(e.data)},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
1740 {NULL} /* Sentinel */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001741};
1742#undef KQ_OFF
1743
1744static PyObject *
Georg Brandlc0e22b72010-03-14 10:51:01 +00001745
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001746kqueue_event_repr(kqueue_event_Object *s)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 char buf[1024];
1749 PyOS_snprintf(
1750 buf, sizeof(buf),
1751 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
1752 "data=0x%zd udata=%p>",
1753 (size_t)(s->e.ident), s->e.filter, s->e.flags,
1754 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
1755 return PyUnicode_FromString(buf);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001756}
1757
1758static int
1759kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
1760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 PyObject *pfd;
1762 static char *kwlist[] = {"ident", "filter", "flags", "fflags",
1763 "data", "udata", NULL};
Christian Heimesf1fe1592013-08-25 14:57:00 +02001764 static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1769 &pfd, &(self->e.filter), &(self->e.flags),
1770 &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
1771 return -1;
1772 }
1773
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001774 if (PyLong_Check(pfd)
1775#if IDENT_TYPE == T_UINT
Christian Heimesaf01f662013-12-21 16:19:10 +01001776 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001777#endif
1778 ) {
1779 self->e.ident = IDENT_AsType(pfd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 }
1781 else {
1782 self->e.ident = PyObject_AsFileDescriptor(pfd);
1783 }
1784 if (PyErr_Occurred()) {
1785 return -1;
1786 }
1787 return 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001788}
1789
1790static PyObject *
1791kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 int op)
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 Py_intptr_t result = 0;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 if (!kqueue_event_Check(o)) {
1797 if (op == Py_EQ || op == Py_NE) {
1798 PyObject *res = op == Py_EQ ? Py_False : Py_True;
1799 Py_INCREF(res);
1800 return res;
1801 }
1802 PyErr_Format(PyExc_TypeError,
1803 "can't compare %.200s to %.200s",
1804 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
1805 return NULL;
1806 }
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001807 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 ((result = s->e.filter - o->e.filter) == 0) &&
1809 ((result = s->e.flags - o->e.flags) == 0) &&
Charles-Francois Natali002a77d2013-05-06 21:24:31 +02001810 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 ((result = s->e.data - o->e.data) == 0) &&
1812 ((result = s->e.udata - o->e.udata) == 0)
1813 ) {
1814 result = 0;
1815 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 switch (op) {
Guido van Rossumee07b942013-12-06 17:46:22 -08001818 case Py_EQ:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 result = (result == 0);
1820 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001821 case Py_NE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 result = (result != 0);
1823 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001824 case Py_LE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 result = (result <= 0);
1826 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001827 case Py_GE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 result = (result >= 0);
1829 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001830 case Py_LT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 result = (result < 0);
1832 break;
Guido van Rossumee07b942013-12-06 17:46:22 -08001833 case Py_GT:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 result = (result > 0);
1835 break;
1836 }
1837 return PyBool_FromLong((long)result);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001838}
1839
1840static PyTypeObject kqueue_event_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 PyVarObject_HEAD_INIT(NULL, 0)
1842 "select.kevent", /* tp_name */
1843 sizeof(kqueue_event_Object), /* tp_basicsize */
1844 0, /* tp_itemsize */
1845 0, /* tp_dealloc */
1846 0, /* tp_print */
1847 0, /* tp_getattr */
1848 0, /* tp_setattr */
1849 0, /* tp_reserved */
1850 (reprfunc)kqueue_event_repr, /* tp_repr */
1851 0, /* tp_as_number */
1852 0, /* tp_as_sequence */
1853 0, /* tp_as_mapping */
1854 0, /* tp_hash */
1855 0, /* tp_call */
1856 0, /* tp_str */
1857 0, /* tp_getattro */
1858 0, /* tp_setattro */
1859 0, /* tp_as_buffer */
1860 Py_TPFLAGS_DEFAULT, /* tp_flags */
1861 kqueue_event_doc, /* tp_doc */
1862 0, /* tp_traverse */
1863 0, /* tp_clear */
1864 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
1865 0, /* tp_weaklistoffset */
1866 0, /* tp_iter */
1867 0, /* tp_iternext */
1868 0, /* tp_methods */
1869 kqueue_event_members, /* tp_members */
1870 0, /* tp_getset */
1871 0, /* tp_base */
1872 0, /* tp_dict */
1873 0, /* tp_descr_get */
1874 0, /* tp_descr_set */
1875 0, /* tp_dictoffset */
1876 (initproc)kqueue_event_init, /* tp_init */
1877 0, /* tp_alloc */
1878 0, /* tp_new */
1879 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001880};
1881
1882static PyObject *
1883kqueue_queue_err_closed(void)
1884{
Victor Stinner13423c32013-08-22 00:19:50 +02001885 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001887}
1888
1889static int
1890kqueue_queue_internal_close(kqueue_queue_Object *self)
1891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 int save_errno = 0;
1893 if (self->kqfd >= 0) {
1894 int kqfd = self->kqfd;
1895 self->kqfd = -1;
1896 Py_BEGIN_ALLOW_THREADS
1897 if (close(kqfd) < 0)
1898 save_errno = errno;
1899 Py_END_ALLOW_THREADS
1900 }
1901 return save_errno;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001902}
1903
1904static PyObject *
1905newKqueue_Object(PyTypeObject *type, SOCKET fd)
1906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 kqueue_queue_Object *self;
1908 assert(type != NULL && type->tp_alloc != NULL);
1909 self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
1910 if (self == NULL) {
1911 return NULL;
1912 }
1913
1914 if (fd == -1) {
1915 Py_BEGIN_ALLOW_THREADS
1916 self->kqfd = kqueue();
1917 Py_END_ALLOW_THREADS
1918 }
1919 else {
1920 self->kqfd = fd;
1921 }
1922 if (self->kqfd < 0) {
1923 Py_DECREF(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001924 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 return NULL;
1926 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02001927
1928 if (fd == -1) {
1929 if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) {
1930 Py_DECREF(self);
1931 return NULL;
1932 }
1933 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 return (PyObject *)self;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001935}
1936
1937static PyObject *
1938kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 if ((args != NULL && PyObject_Size(args)) ||
1941 (kwds != NULL && PyObject_Size(kwds))) {
1942 PyErr_SetString(PyExc_ValueError,
1943 "select.kqueue doesn't accept arguments");
1944 return NULL;
1945 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 return newKqueue_Object(type, -1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001948}
1949
1950static void
1951kqueue_queue_dealloc(kqueue_queue_Object *self)
1952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 kqueue_queue_internal_close(self);
1954 Py_TYPE(self)->tp_free(self);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001955}
1956
1957static PyObject*
1958kqueue_queue_close(kqueue_queue_Object *self)
1959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 errno = kqueue_queue_internal_close(self);
1961 if (errno < 0) {
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001962 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 return NULL;
1964 }
1965 Py_RETURN_NONE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001966}
1967
1968PyDoc_STRVAR(kqueue_queue_close_doc,
1969"close() -> None\n\
1970\n\
1971Close the kqueue control file descriptor. Further operations on the kqueue\n\
1972object will raise an exception.");
1973
1974static PyObject*
1975kqueue_queue_get_closed(kqueue_queue_Object *self)
1976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 if (self->kqfd < 0)
1978 Py_RETURN_TRUE;
1979 else
1980 Py_RETURN_FALSE;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001981}
1982
1983static PyObject*
1984kqueue_queue_fileno(kqueue_queue_Object *self)
1985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 if (self->kqfd < 0)
1987 return kqueue_queue_err_closed();
1988 return PyLong_FromLong(self->kqfd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00001989}
1990
1991PyDoc_STRVAR(kqueue_queue_fileno_doc,
1992"fileno() -> int\n\
1993\n\
1994Return the kqueue control file descriptor.");
1995
1996static PyObject*
1997kqueue_queue_fromfd(PyObject *cls, PyObject *args)
1998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 SOCKET fd;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
2002 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 return newKqueue_Object((PyTypeObject*)cls, fd);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002005}
2006
2007PyDoc_STRVAR(kqueue_queue_fromfd_doc,
2008"fromfd(fd) -> kqueue\n\
2009\n\
2010Create a kqueue object from a given control fd.");
2011
2012static PyObject *
2013kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
2014{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 int nevents = 0;
2016 int gotevents = 0;
2017 int nchanges = 0;
2018 int i = 0;
2019 PyObject *otimeout = NULL;
2020 PyObject *ch = NULL;
2021 PyObject *it = NULL, *ei = NULL;
2022 PyObject *result = NULL;
2023 struct kevent *evl = NULL;
2024 struct kevent *chl = NULL;
Victor Stinnerd327f9d2012-03-13 15:29:08 +01002025 struct timespec timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 struct timespec *ptimeoutspec;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 if (self->kqfd < 0)
2029 return kqueue_queue_err_closed();
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
2032 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 if (nevents < 0) {
2035 PyErr_Format(PyExc_ValueError,
2036 "Length of eventlist must be 0 or positive, got %d",
2037 nevents);
2038 return NULL;
2039 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 if (otimeout == Py_None || otimeout == NULL) {
2042 ptimeoutspec = NULL;
2043 }
2044 else if (PyNumber_Check(otimeout)) {
Victor Stinner3c1b3792014-02-17 00:02:43 +01002045 if (_PyTime_ObjectToTimespec(otimeout, &timeout.tv_sec,
2046 &timeout.tv_nsec, _PyTime_ROUND_UP) == -1)
Victor Stinner5d272cc2012-03-13 13:35:55 +01002047 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002048
Victor Stinner5d272cc2012-03-13 13:35:55 +01002049 if (timeout.tv_sec < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 PyErr_SetString(PyExc_ValueError,
2051 "timeout must be positive or None");
2052 return NULL;
2053 }
Victor Stinnerd528b012012-03-13 16:25:35 +01002054 ptimeoutspec = &timeout;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 }
2056 else {
2057 PyErr_Format(PyExc_TypeError,
2058 "timeout argument must be an number "
2059 "or None, got %.200s",
2060 Py_TYPE(otimeout)->tp_name);
2061 return NULL;
2062 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 if (ch != NULL && ch != Py_None) {
2065 it = PyObject_GetIter(ch);
2066 if (it == NULL) {
2067 PyErr_SetString(PyExc_TypeError,
2068 "changelist is not iterable");
2069 return NULL;
2070 }
2071 nchanges = PyObject_Size(ch);
2072 if (nchanges < 0) {
2073 goto error;
2074 }
Georg Brandlc0e22b72010-03-14 10:51:01 +00002075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 chl = PyMem_New(struct kevent, nchanges);
2077 if (chl == NULL) {
2078 PyErr_NoMemory();
2079 goto error;
2080 }
2081 i = 0;
2082 while ((ei = PyIter_Next(it)) != NULL) {
2083 if (!kqueue_event_Check(ei)) {
2084 Py_DECREF(ei);
2085 PyErr_SetString(PyExc_TypeError,
2086 "changelist must be an iterable of "
2087 "select.kevent objects");
2088 goto error;
2089 } else {
2090 chl[i++] = ((kqueue_event_Object *)ei)->e;
2091 }
2092 Py_DECREF(ei);
2093 }
2094 }
2095 Py_CLEAR(it);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 /* event list */
2098 if (nevents) {
2099 evl = PyMem_New(struct kevent, nevents);
2100 if (evl == NULL) {
2101 PyErr_NoMemory();
2102 goto error;
2103 }
2104 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 Py_BEGIN_ALLOW_THREADS
2107 gotevents = kevent(self->kqfd, chl, nchanges,
2108 evl, nevents, ptimeoutspec);
2109 Py_END_ALLOW_THREADS
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 if (gotevents == -1) {
2112 PyErr_SetFromErrno(PyExc_OSError);
2113 goto error;
2114 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 result = PyList_New(gotevents);
2117 if (result == NULL) {
2118 goto error;
2119 }
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 for (i = 0; i < gotevents; i++) {
2122 kqueue_event_Object *ch;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
2125 if (ch == NULL) {
2126 goto error;
2127 }
2128 ch->e = evl[i];
2129 PyList_SET_ITEM(result, i, (PyObject *)ch);
2130 }
2131 PyMem_Free(chl);
2132 PyMem_Free(evl);
2133 return result;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002134
2135 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 PyMem_Free(chl);
2137 PyMem_Free(evl);
2138 Py_XDECREF(result);
2139 Py_XDECREF(it);
2140 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002141}
2142
2143PyDoc_STRVAR(kqueue_queue_control_doc,
Benjamin Peterson9bc93512008-09-22 22:10:59 +00002144"control(changelist, max_events[, timeout=None]) -> eventlist\n\
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002145\n\
2146Calls the kernel kevent function.\n\
2147- changelist must be a list of kevent objects describing the changes\n\
2148 to be made to the kernel's watch list or None.\n\
2149- max_events lets you specify the maximum number of events that the\n\
2150 kernel will return.\n\
2151- timeout is the maximum time to wait in seconds, or else None,\n\
2152 to wait forever. timeout accepts floats for smaller timeouts, too.");
2153
2154
2155static PyMethodDef kqueue_queue_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 {"fromfd", (PyCFunction)kqueue_queue_fromfd,
2157 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
2158 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
2159 kqueue_queue_close_doc},
2160 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
2161 kqueue_queue_fileno_doc},
2162 {"control", (PyCFunction)kqueue_queue_control,
2163 METH_VARARGS , kqueue_queue_control_doc},
2164 {NULL, NULL},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002165};
2166
2167static PyGetSetDef kqueue_queue_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 {"closed", (getter)kqueue_queue_get_closed, NULL,
2169 "True if the kqueue handler is closed"},
2170 {0},
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002171};
2172
2173PyDoc_STRVAR(kqueue_queue_doc,
2174"Kqueue syscall wrapper.\n\
2175\n\
2176For example, to start watching a socket for input:\n\
2177>>> kq = kqueue()\n\
2178>>> sock = socket()\n\
2179>>> sock.connect((host, port))\n\
2180>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
2181\n\
2182To wait one second for it to become writeable:\n\
2183>>> kq.control(None, 1, 1000)\n\
2184\n\
2185To stop listening:\n\
2186>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
2187
2188static PyTypeObject kqueue_queue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 PyVarObject_HEAD_INIT(NULL, 0)
2190 "select.kqueue", /* tp_name */
2191 sizeof(kqueue_queue_Object), /* tp_basicsize */
2192 0, /* tp_itemsize */
2193 (destructor)kqueue_queue_dealloc, /* tp_dealloc */
2194 0, /* tp_print */
2195 0, /* tp_getattr */
2196 0, /* tp_setattr */
2197 0, /* tp_reserved */
2198 0, /* tp_repr */
2199 0, /* tp_as_number */
2200 0, /* tp_as_sequence */
2201 0, /* tp_as_mapping */
2202 0, /* tp_hash */
2203 0, /* tp_call */
2204 0, /* tp_str */
2205 0, /* tp_getattro */
2206 0, /* tp_setattro */
2207 0, /* tp_as_buffer */
2208 Py_TPFLAGS_DEFAULT, /* tp_flags */
2209 kqueue_queue_doc, /* tp_doc */
2210 0, /* tp_traverse */
2211 0, /* tp_clear */
2212 0, /* tp_richcompare */
2213 0, /* tp_weaklistoffset */
2214 0, /* tp_iter */
2215 0, /* tp_iternext */
2216 kqueue_queue_methods, /* tp_methods */
2217 0, /* tp_members */
2218 kqueue_queue_getsetlist, /* tp_getset */
2219 0, /* tp_base */
2220 0, /* tp_dict */
2221 0, /* tp_descr_get */
2222 0, /* tp_descr_set */
2223 0, /* tp_dictoffset */
2224 0, /* tp_init */
2225 0, /* tp_alloc */
2226 kqueue_queue_new, /* tp_new */
2227 0, /* tp_free */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002228};
2229
2230#endif /* HAVE_KQUEUE */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002231
2232
2233
2234
2235
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002236/* ************************************************************************ */
2237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002238PyDoc_STRVAR(select_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002239"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
2240\n\
2241Wait until one or more file descriptors are ready for some kind of I/O.\n\
Brett Cannon62dba4c2003-09-10 19:37:42 +00002242The first three arguments are sequences of file descriptors to be waited for:\n\
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002243rlist -- wait until ready for reading\n\
2244wlist -- wait until ready for writing\n\
2245xlist -- wait for an ``exceptional condition''\n\
2246If only one kind of condition is required, pass [] for the other lists.\n\
2247A file descriptor is either a socket or file object, or a small integer\n\
2248gotten from a fileno() method call on one of those.\n\
2249\n\
2250The optional 4th argument specifies a timeout in seconds; it may be\n\
2251a floating point number to specify fractions of seconds. If it is absent\n\
2252or None, the call will never time out.\n\
2253\n\
2254The return value is a tuple of three lists corresponding to the first three\n\
2255arguments; each contains the subset of the corresponding file descriptors\n\
2256that are ready.\n\
2257\n\
2258*** IMPORTANT NOTICE ***\n\
Christian Heimesaf01f662013-12-21 16:19:10 +01002259On Windows only sockets are supported; on Unix, all file\n\
Christian Heimesf6cd9672008-03-26 13:45:42 +00002260descriptors can be used.");
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002261
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00002262static PyMethodDef select_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 {"select", select_select, METH_VARARGS, select_doc},
Charles-François Natali986a56c2013-01-19 12:19:10 +01002264#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 {"poll", select_poll, METH_NOARGS, poll_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +00002266#endif /* HAVE_POLL */
Jesus Cead8b9ae62011-11-14 19:07:41 +01002267#ifdef HAVE_SYS_DEVPOLL_H
2268 {"devpoll", select_devpoll, METH_NOARGS, devpoll_doc},
2269#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +00002271};
2272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002273PyDoc_STRVAR(module_doc,
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +00002274"This module supports asynchronous I/O on multiple file descriptors.\n\
2275\n\
2276*** IMPORTANT NOTICE ***\n\
Christian Heimesaf01f662013-12-21 16:19:10 +01002277On Windows only sockets are supported; on Unix, all file descriptors.");
Guido van Rossumed233a51992-06-23 09:07:03 +00002278
Martin v. Löwis1a214512008-06-11 05:26:20 +00002279
2280static struct PyModuleDef selectmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 PyModuleDef_HEAD_INIT,
2282 "select",
2283 module_doc,
2284 -1,
2285 select_methods,
2286 NULL,
2287 NULL,
2288 NULL,
2289 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002290};
2291
Jesus Cead8b9ae62011-11-14 19:07:41 +01002292
2293
2294
Mark Hammond62b1ab12002-07-23 06:31:15 +00002295PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002296PyInit_select(void)
Guido van Rossumed233a51992-06-23 09:07:03 +00002297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 PyObject *m;
2299 m = PyModule_Create(&selectmodule);
2300 if (m == NULL)
2301 return NULL;
Fred Drake4baedc12002-04-01 14:53:37 +00002302
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002303 Py_INCREF(PyExc_OSError);
2304 PyModule_AddObject(m, "error", PyExc_OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002305
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002306#ifdef PIPE_BUF
R. David Murraye16cda92010-10-15 23:12:57 +00002307#ifdef HAVE_BROKEN_PIPE_BUF
2308#undef PIPE_BUF
2309#define PIPE_BUF 512
2310#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002311 PyModule_AddIntMacro(m, PIPE_BUF);
Amaury Forgeot d'Arcace31022009-07-09 22:44:11 +00002312#endif
Gregory P. Smithb970b862009-07-04 02:28:47 +00002313
Charles-François Natali986a56c2013-01-19 12:19:10 +01002314#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002315#ifdef __APPLE__
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 if (select_have_broken_poll()) {
2317 if (PyObject_DelAttrString(m, "poll") == -1) {
2318 PyErr_Clear();
2319 }
2320 } else {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002321#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002323#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 if (PyType_Ready(&poll_Type) < 0)
2325 return NULL;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002326 PyModule_AddIntMacro(m, POLLIN);
2327 PyModule_AddIntMacro(m, POLLPRI);
2328 PyModule_AddIntMacro(m, POLLOUT);
2329 PyModule_AddIntMacro(m, POLLERR);
2330 PyModule_AddIntMacro(m, POLLHUP);
2331 PyModule_AddIntMacro(m, POLLNVAL);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +00002332
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002333#ifdef POLLRDNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002334 PyModule_AddIntMacro(m, POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002335#endif
2336#ifdef POLLRDBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002337 PyModule_AddIntMacro(m, POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002338#endif
2339#ifdef POLLWRNORM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002340 PyModule_AddIntMacro(m, POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002341#endif
2342#ifdef POLLWRBAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002343 PyModule_AddIntMacro(m, POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +00002344#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002345#ifdef POLLMSG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002346 PyModule_AddIntMacro(m, POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +00002347#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002349#endif /* HAVE_POLL */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002350
Jesus Cead8b9ae62011-11-14 19:07:41 +01002351#ifdef HAVE_SYS_DEVPOLL_H
2352 if (PyType_Ready(&devpoll_Type) < 0)
2353 return NULL;
2354#endif
2355
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002356#ifdef HAVE_EPOLL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 Py_TYPE(&pyEpoll_Type) = &PyType_Type;
2358 if (PyType_Ready(&pyEpoll_Type) < 0)
2359 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 Py_INCREF(&pyEpoll_Type);
2362 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002363
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002364 PyModule_AddIntMacro(m, EPOLLIN);
2365 PyModule_AddIntMacro(m, EPOLLOUT);
2366 PyModule_AddIntMacro(m, EPOLLPRI);
2367 PyModule_AddIntMacro(m, EPOLLERR);
2368 PyModule_AddIntMacro(m, EPOLLHUP);
2369 PyModule_AddIntMacro(m, EPOLLET);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002370#ifdef EPOLLONESHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002371 /* Kernel 2.6.2+ */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002372 PyModule_AddIntMacro(m, EPOLLONESHOT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002373#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002375 PyModule_AddIntMacro(m, EPOLLRDNORM);
2376 PyModule_AddIntMacro(m, EPOLLRDBAND);
2377 PyModule_AddIntMacro(m, EPOLLWRNORM);
2378 PyModule_AddIntMacro(m, EPOLLWRBAND);
2379 PyModule_AddIntMacro(m, EPOLLMSG);
Benjamin Peterson2fb9ae92011-12-27 15:15:41 -06002380
Benjamin Peterson95c16622011-12-27 15:36:32 -06002381#ifdef EPOLL_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02002382 PyModule_AddIntMacro(m, EPOLL_CLOEXEC);
Benjamin Peterson95c16622011-12-27 15:36:32 -06002383#endif
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002384#endif /* HAVE_EPOLL */
2385
2386#ifdef HAVE_KQUEUE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 kqueue_event_Type.tp_new = PyType_GenericNew;
2388 Py_TYPE(&kqueue_event_Type) = &PyType_Type;
2389 if(PyType_Ready(&kqueue_event_Type) < 0)
2390 return NULL;
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 Py_INCREF(&kqueue_event_Type);
2393 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
2396 if(PyType_Ready(&kqueue_queue_Type) < 0)
2397 return NULL;
2398 Py_INCREF(&kqueue_queue_Type);
2399 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
2400
2401 /* event filters */
2402 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
2403 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
2404 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
2405 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
2406 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002407#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002409#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
2411 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 /* event flags */
2414 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
2415 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
2416 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
2417 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
2418 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
2419 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
2422 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
2425 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 /* READ WRITE filter flag */
2428 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 /* VNODE filter flags */
2431 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
2432 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
2433 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
2434 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
2435 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
2436 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
2437 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 /* PROC filter flags */
2440 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
2441 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
2442 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
2443 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
2444 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
2447 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
2448 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
2449
2450 /* NETDEV filter flags */
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002451#ifdef EVFILT_NETDEV
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
2453 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
2454 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
Christian Heimes4fbc72b2008-03-22 00:47:35 +00002455#endif
2456
2457#endif /* HAVE_KQUEUE */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 return m;
Guido van Rossumed233a51992-06-23 09:07:03 +00002459}