blob: c92dc7f18ab9bf602e4e3626d7a2bd46e91e9f05 [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 Rossumbcc20741998-08-04 22:53:56 +00005 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
6 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00007*/
Guido van Rossumed233a51992-06-23 09:07:03 +00008
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00009#include "Python.h"
Guido van Rossumed233a51992-06-23 09:07:03 +000010
Tim Petersd92dfe02000-12-12 01:18:41 +000011/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
12 64 is too small (too many people have bumped into that limit).
13 Here we boost it.
14 Users who want even more than the boosted limit should #define
15 FD_SETSIZE higher before this; e.g., via compiler /D switch.
16*/
17#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
18#define FD_SETSIZE 512
19#endif
20
Guido van Rossuma376cc51996-12-05 23:43:35 +000021#ifdef HAVE_UNISTD_H
22#include <unistd.h>
23#endif
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000024#if defined(HAVE_POLL_H)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000025#include <poll.h>
Andrew M. Kuchling737fbb32001-07-14 20:54:37 +000026#elif defined(HAVE_SYS_POLL_H)
27#include <sys/poll.h>
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000028#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000029
Guido van Rossum37273171996-12-09 18:47:43 +000030#ifdef __sgi
31/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000032extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000033#endif
34
Guido van Rossumff7e83d1999-08-27 20:39:37 +000035#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000036#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000037#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000038
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000039#if defined(PYOS_OS2)
40#include <sys/time.h>
41#include <utils.h>
42#endif
43
Guido van Rossum6f489d91996-06-28 20:15:15 +000044#ifdef MS_WINDOWS
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000045#include <winsock.h>
46#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000047#ifdef __BEOS__
48#include <net/socket.h>
49#define SOCKET int
50#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051#define SOCKET int
52#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000053#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000054
Guido van Rossum1ca8bb32001-03-02 06:28:17 +000055#ifdef RISCOS
56#define NO_DUP
57#undef off_t
58#undef uid_t
59#undef gid_t
60#undef errno
61#include "socklib.h"
62#endif /* RISCOS */
63
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000064static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000065
Barry Warsawc1cb3601996-12-12 22:16:21 +000066/* list of Python objects and their file descriptor */
67typedef struct {
68 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000069 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000070 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000071} pylist;
72
Barry Warsawc1cb3601996-12-12 22:16:21 +000073static void
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000074reap_obj(pylist fd2obj[FD_SETSIZE + 3])
Barry Warsawc1cb3601996-12-12 22:16:21 +000075{
76 int i;
77 for (i = 0; i < FD_SETSIZE + 3 && fd2obj[i].sentinel >= 0; i++) {
78 Py_XDECREF(fd2obj[i].obj);
79 fd2obj[i].obj = NULL;
80 }
81 fd2obj[0].sentinel = -1;
82}
83
84
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000085/* returns -1 and sets the Python exception if an error occurred, otherwise
86 returns a number >= 0
87*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000088static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000089list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +000090{
Barry Warsawc1cb3601996-12-12 22:16:21 +000091 int i;
92 int max = -1;
93 int index = 0;
94 int len = PyList_Size(list);
95 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000096
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000097 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000098 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000099
100 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000101 SOCKET v;
102
103 /* any intervening fileno() calls could decr this refcnt */
Barry Warsaw24c4b3d1996-12-13 23:22:42 +0000104 if (!(o = PyList_GetItem(list, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +0000105 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +0000106
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +0000108 v = PyObject_AsFileDescriptor( o );
109 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000110
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000111#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112 max = 0; /* not used for Win32 */
113#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000114 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115 PyErr_SetString(PyExc_ValueError,
116 "filedescriptor out of range in select()");
117 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000118 }
119 if (v > max)
120 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000121#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000122 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000123
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000124 /* add object and its file descriptor to the list */
125 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126 PyErr_SetString(PyExc_ValueError,
127 "too many file descriptors in select()");
128 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000129 }
130 fd2obj[index].obj = o;
131 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000132 fd2obj[index].sentinel = 0;
133 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000134 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000135 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000136
137 finally:
138 Py_XDECREF(o);
139 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000140}
141
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000142/* returns NULL and sets the Python exception if an error occurred */
143static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +0000145{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000146 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000147 PyObject *list, *o;
148 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000149
Barry Warsawc1cb3601996-12-12 22:16:21 +0000150 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000151 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000152 count++;
153 }
154 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000155 if (!list)
156 return NULL;
157
Barry Warsawc1cb3601996-12-12 22:16:21 +0000158 i = 0;
159 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000160 fd = fd2obj[j].fd;
161 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000162#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000163 if (fd > FD_SETSIZE) {
164 PyErr_SetString(PyExc_SystemError,
165 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000166 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000167 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000168#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000169 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000170 fd2obj[j].obj = NULL;
171 /* transfer ownership */
172 if (PyList_SetItem(list, i, o) < 0)
173 goto finally;
174
175 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000176 }
177 }
178 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000179 finally:
180 Py_DECREF(list);
181 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000182}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000183
Guido van Rossumed233a51992-06-23 09:07:03 +0000184
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000185static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000186select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000187{
Guido van Rossumd20781b1998-07-02 02:53:36 +0000188#ifdef MS_WINDOWS
189 /* This would be an awful lot of stack space on Windows! */
190 pylist *rfd2obj, *wfd2obj, *efd2obj;
191#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000192 pylist rfd2obj[FD_SETSIZE + 3];
193 pylist wfd2obj[FD_SETSIZE + 3];
194 pylist efd2obj[FD_SETSIZE + 3];
Guido van Rossumd20781b1998-07-02 02:53:36 +0000195#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000196 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000197 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000198 PyObject *tout = Py_None;
199 fd_set ifdset, ofdset, efdset;
200 double timeout;
201 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000202 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000203 int imax, omax, emax, max;
204 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000205
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000206 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000207 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000208 &ifdlist, &ofdlist, &efdlist, &tout))
209 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000210
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000211 if (tout == Py_None)
212 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000213 else if (!PyArg_Parse(tout, "d", &timeout)) {
214 PyErr_SetString(PyExc_TypeError,
215 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000216 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000217 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000218 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000219 if (timeout > (double)LONG_MAX) {
220 PyErr_SetString(PyExc_OverflowError, "timeout period too long");
221 return NULL;
222 }
223 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000224 timeout = timeout - (double)seconds;
225 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000226 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000227 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000228 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000229
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000230 /* sanity check first three arguments */
231 if (!PyList_Check(ifdlist) ||
232 !PyList_Check(ofdlist) ||
233 !PyList_Check(efdlist))
234 {
235 PyErr_SetString(PyExc_TypeError,
236 "arguments 1-3 must be lists");
237 return NULL;
238 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000239
Guido van Rossumd20781b1998-07-02 02:53:36 +0000240#ifdef MS_WINDOWS
241 /* Allocate memory for the lists */
242 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
243 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
244 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
245 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000246 if (rfd2obj) PyMem_DEL(rfd2obj);
247 if (wfd2obj) PyMem_DEL(wfd2obj);
248 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000249 return NULL;
250 }
251#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000252 /* Convert lists to fd_sets, and get maximum fd number
253 * propagates the Python exception set in list2set()
254 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000255 rfd2obj[0].sentinel = -1;
256 wfd2obj[0].sentinel = -1;
257 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000258 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000259 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000260 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000261 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000262 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000263 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000264 max = imax;
265 if (omax > max) max = omax;
266 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000267
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000268 Py_BEGIN_ALLOW_THREADS
269 n = select(max, &ifdset, &ofdset, &efdset, tvp);
270 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000271
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000272 if (n < 0) {
273 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000275 else if (n == 0) {
276 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000277 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000278 if (ifdlist) {
279 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
280 Py_DECREF(ifdlist);
281 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000282 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000283 else {
284 /* any of these three calls can raise an exception. it's more
285 convenient to test for this after all three calls... but
286 is that acceptable?
287 */
288 ifdlist = set2list(&ifdset, rfd2obj);
289 ofdlist = set2list(&ofdset, wfd2obj);
290 efdlist = set2list(&efdset, efd2obj);
291 if (PyErr_Occurred())
292 ret = NULL;
293 else
294 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000295
Barry Warsawc1cb3601996-12-12 22:16:21 +0000296 Py_DECREF(ifdlist);
297 Py_DECREF(ofdlist);
298 Py_DECREF(efdlist);
299 }
300
301 finally:
302 reap_obj(rfd2obj);
303 reap_obj(wfd2obj);
304 reap_obj(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000305#ifdef MS_WINDOWS
306 PyMem_DEL(rfd2obj);
307 PyMem_DEL(wfd2obj);
308 PyMem_DEL(efd2obj);
309#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000310 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000311}
312
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000313#ifdef HAVE_POLL
314/*
315 * poll() support
316 */
317
318typedef struct {
319 PyObject_HEAD
320 PyObject *dict;
321 int ufd_uptodate;
322 int ufd_len;
323 struct pollfd *ufds;
324} pollObject;
325
326staticforward PyTypeObject poll_Type;
327
328/* Update the malloc'ed array of pollfds to match the dictionary
329 contained within a pollObject. Return 1 on success, 0 on an error.
330*/
331
332static int
333update_ufd_array(pollObject *self)
334{
Fred Drakedff3a372001-07-19 21:29:49 +0000335 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000336 PyObject *key, *value;
337
338 self->ufd_len = PyDict_Size(self->dict);
339 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
340 if (self->ufds == NULL) {
341 PyErr_NoMemory();
342 return 0;
343 }
344
345 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000346 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000347 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000348 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000349 i++;
350 }
351 self->ufd_uptodate = 1;
352 return 1;
353}
354
355static char poll_register_doc[] =
356"register(fd [, eventmask] ) -> None\n\n\
357Register a file descriptor with the polling object.\n\
358fd -- either an integer, or an object with a fileno() method returning an int.\n\
359events -- an optional bitmask describing the type of events to check for";
360
361static PyObject *
362poll_register(pollObject *self, PyObject *args)
363{
364 PyObject *o, *key, *value;
365 int fd, events = POLLIN | POLLPRI | POLLOUT;
366
Fred Drake7b87f852001-05-21 03:29:05 +0000367 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000368 return NULL;
369 }
370
371 fd = PyObject_AsFileDescriptor(o);
372 if (fd == -1) return NULL;
373
374 /* Add entry to the internal dictionary: the key is the
375 file descriptor, and the value is the event mask. */
376 if ( (NULL == (key = PyInt_FromLong(fd))) ||
377 (NULL == (value = PyInt_FromLong(events))) ||
378 (PyDict_SetItem(self->dict, key, value)) == -1) {
379 return NULL;
380 }
381 self->ufd_uptodate = 0;
382
383 Py_INCREF(Py_None);
384 return Py_None;
385}
386
387static char poll_unregister_doc[] =
388"unregister(fd) -> None\n\n\
389Remove a file descriptor being tracked by the polling object.";
390
391static PyObject *
392poll_unregister(pollObject *self, PyObject *args)
393{
394 PyObject *o, *key;
395 int fd;
396
Fred Drake7b87f852001-05-21 03:29:05 +0000397 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000398 return NULL;
399 }
400
401 fd = PyObject_AsFileDescriptor( o );
402 if (fd == -1)
403 return NULL;
404
405 /* Check whether the fd is already in the array */
406 key = PyInt_FromLong(fd);
407 if (key == NULL)
408 return NULL;
409
410 if (PyDict_DelItem(self->dict, key) == -1) {
411 Py_DECREF(key);
412 /* This will simply raise the KeyError set by PyDict_DelItem
413 if the file descriptor isn't registered. */
414 return NULL;
415 }
416
417 Py_DECREF(key);
418 self->ufd_uptodate = 0;
419
420 Py_INCREF(Py_None);
421 return Py_None;
422}
423
424static char poll_poll_doc[] =
425"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
426Polls the set of registered file descriptors, returning a list containing \n\
427any descriptors that have events or errors to report.";
428
429static PyObject *
430poll_poll(pollObject *self, PyObject *args)
431{
432 PyObject *result_list = NULL, *tout = NULL;
433 int timeout = 0, poll_result, i, j;
434 PyObject *value = NULL, *num = NULL;
435
Fred Drake7b87f852001-05-21 03:29:05 +0000436 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000437 return NULL;
438 }
439
440 /* Check values for timeout */
441 if (tout == NULL || tout == Py_None)
442 timeout = -1;
443 else if (!PyArg_Parse(tout, "i", &timeout)) {
444 PyErr_SetString(PyExc_TypeError,
445 "timeout must be an integer or None");
446 return NULL;
447 }
448
449 /* Ensure the ufd array is up to date */
450 if (!self->ufd_uptodate)
451 if (update_ufd_array(self) == 0)
452 return NULL;
453
454 /* call poll() */
455 Py_BEGIN_ALLOW_THREADS;
456 poll_result = poll(self->ufds, self->ufd_len, timeout);
457 Py_END_ALLOW_THREADS;
458
459 if (poll_result < 0) {
460 PyErr_SetFromErrno(SelectError);
461 return NULL;
462 }
463
464 /* build the result list */
465
466 result_list = PyList_New(poll_result);
467 if (!result_list)
468 return NULL;
469 else {
470 for (i = 0, j = 0; j < poll_result; j++) {
471 /* skip to the next fired descriptor */
472 while (!self->ufds[i].revents) {
473 i++;
474 }
475 /* if we hit a NULL return, set value to NULL
476 and break out of loop; code at end will
477 clean up result_list */
478 value = PyTuple_New(2);
479 if (value == NULL)
480 goto error;
481 num = PyInt_FromLong(self->ufds[i].fd);
482 if (num == NULL) {
483 Py_DECREF(value);
484 goto error;
485 }
486 PyTuple_SET_ITEM(value, 0, num);
487
488 num = PyInt_FromLong(self->ufds[i].revents);
489 if (num == NULL) {
490 Py_DECREF(value);
491 goto error;
492 }
493 PyTuple_SET_ITEM(value, 1, num);
494 if ((PyList_SetItem(result_list, j, value)) == -1) {
495 Py_DECREF(value);
496 goto error;
497 }
498 i++;
499 }
500 }
501 return result_list;
502
503 error:
504 Py_DECREF(result_list);
505 return NULL;
506}
507
508static PyMethodDef poll_methods[] = {
509 {"register", (PyCFunction)poll_register,
510 METH_VARARGS, poll_register_doc},
511 {"unregister", (PyCFunction)poll_unregister,
512 METH_VARARGS, poll_unregister_doc},
513 {"poll", (PyCFunction)poll_poll,
514 METH_VARARGS, poll_poll_doc},
515 {NULL, NULL} /* sentinel */
516};
517
518static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000519newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000520{
521 pollObject *self;
522 self = PyObject_New(pollObject, &poll_Type);
523 if (self == NULL)
524 return NULL;
525 /* ufd_uptodate is a Boolean, denoting whether the
526 array pointed to by ufds matches the contents of the dictionary. */
527 self->ufd_uptodate = 0;
528 self->ufds = NULL;
529 self->dict = PyDict_New();
530 if (self->dict == NULL) {
531 Py_DECREF(self);
532 return NULL;
533 }
534 return self;
535}
536
537static void
538poll_dealloc(pollObject *self)
539{
540 if (self->ufds != NULL)
541 PyMem_DEL(self->ufds);
542 Py_XDECREF(self->dict);
543 PyObject_Del(self);
544}
545
546static PyObject *
547poll_getattr(pollObject *self, char *name)
548{
549 return Py_FindMethod(poll_methods, (PyObject *)self, name);
550}
551
552statichere PyTypeObject poll_Type = {
553 /* The ob_type field must be initialized in the module init function
554 * to be portable to Windows without using C++. */
555 PyObject_HEAD_INIT(NULL)
556 0, /*ob_size*/
557 "poll", /*tp_name*/
558 sizeof(pollObject), /*tp_basicsize*/
559 0, /*tp_itemsize*/
560 /* methods */
561 (destructor)poll_dealloc, /*tp_dealloc*/
562 0, /*tp_print*/
563 (getattrfunc)poll_getattr, /*tp_getattr*/
564 0, /*tp_setattr*/
565 0, /*tp_compare*/
566 0, /*tp_repr*/
567 0, /*tp_as_number*/
568 0, /*tp_as_sequence*/
569 0, /*tp_as_mapping*/
570 0, /*tp_hash*/
571};
572
573static char poll_doc[] =
574"Returns a polling object, which supports registering and\n\
575unregistering file descriptors, and then polling them for I/O events.";
576
577static PyObject *
578select_poll(PyObject *self, PyObject *args)
579{
580 pollObject *rv;
581
582 if (!PyArg_ParseTuple(args, ":poll"))
583 return NULL;
584 rv = newPollObject();
585 if ( rv == NULL )
586 return NULL;
587 return (PyObject *)rv;
588}
589#endif /* HAVE_POLL */
590
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000591static char select_doc[] =
592"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
593\n\
594Wait until one or more file descriptors are ready for some kind of I/O.\n\
595The first three arguments are lists of file descriptors to be waited for:\n\
596rlist -- wait until ready for reading\n\
597wlist -- wait until ready for writing\n\
598xlist -- wait for an ``exceptional condition''\n\
599If only one kind of condition is required, pass [] for the other lists.\n\
600A file descriptor is either a socket or file object, or a small integer\n\
601gotten from a fileno() method call on one of those.\n\
602\n\
603The optional 4th argument specifies a timeout in seconds; it may be\n\
604a floating point number to specify fractions of seconds. If it is absent\n\
605or None, the call will never time out.\n\
606\n\
607The return value is a tuple of three lists corresponding to the first three\n\
608arguments; each contains the subset of the corresponding file descriptors\n\
609that are ready.\n\
610\n\
611*** IMPORTANT NOTICE ***\n\
612On Windows, only sockets are supported; on Unix, all file descriptors.";
613
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000614static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000615 {"select", select_select, METH_VARARGS, select_doc},
616#ifdef HAVE_POLL
617 {"poll", select_poll, METH_VARARGS, poll_doc},
618#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000619 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000620};
621
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000622static char module_doc[] =
623"This module supports asynchronous I/O on multiple file descriptors.\n\
624\n\
625*** IMPORTANT NOTICE ***\n\
626On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000627
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628/*
629 * Convenience routine to export an integer value.
630 * For simplicity, errors (which are unlikely anyway) are ignored.
631 */
632
633static void
634insint(PyObject *d, char *name, int value)
635{
636 PyObject *v = PyInt_FromLong((long) value);
637 if (v == NULL) {
638 /* Don't bother reporting this error */
639 PyErr_Clear();
640 }
641 else {
642 PyDict_SetItemString(d, name, v);
643 Py_DECREF(v);
644 }
645}
646
Guido van Rossum3886bb61998-12-04 18:50:17 +0000647DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000648initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000649{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000650 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000651 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000652 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000653 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000654 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000655#ifdef HAVE_POLL
656 poll_Type.ob_type = &PyType_Type;
657 insint(d, "POLLIN", POLLIN);
658 insint(d, "POLLPRI", POLLPRI);
659 insint(d, "POLLOUT", POLLOUT);
660 insint(d, "POLLERR", POLLERR);
661 insint(d, "POLLHUP", POLLHUP);
662 insint(d, "POLLNVAL", POLLNVAL);
663
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000664#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000665 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000666#endif
667#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000668 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000669#endif
670#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000671 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000672#endif
673#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000674 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000675#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000676#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000677 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000678#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000679#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000680}