blob: 285f6f046c734ad8b805653062dc9b80659c80ba [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
Barry Warsawb44740f2001-08-16 16:52:59 +0000184#undef SELECT_USES_HEAP
185#if FD_SETSIZE > 1024
186#define SELECT_USES_HEAP
187#endif /* FD_SETSIZE > 1024 */
188
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000189static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000190select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000191{
Barry Warsawb44740f2001-08-16 16:52:59 +0000192#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000193 /* This would be an awful lot of stack space on Windows! */
194 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000195#else /* !SELECT_USES_HEAP */
196 /* XXX: Why, oh why does this add 3?! As far as anyone can tell,
197 * it should only add 1 for the sentinel.
198 *
199 * XXX: All this should probably be implemented as follows:
200 * - find the highest descriptor we're interested in
201 * - add one
202 * - that's the size
203 * See: Stevens, APitUE, $12.5.1
204 */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000205 pylist rfd2obj[FD_SETSIZE + 3];
206 pylist wfd2obj[FD_SETSIZE + 3];
207 pylist efd2obj[FD_SETSIZE + 3];
Barry Warsawb44740f2001-08-16 16:52:59 +0000208#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000209 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000210 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000211 PyObject *tout = Py_None;
212 fd_set ifdset, ofdset, efdset;
213 double timeout;
214 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000215 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000216 int imax, omax, emax, max;
217 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000218
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000219 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000220 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000221 &ifdlist, &ofdlist, &efdlist, &tout))
222 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000223
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000224 if (tout == Py_None)
225 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000226 else if (!PyArg_Parse(tout, "d", &timeout)) {
227 PyErr_SetString(PyExc_TypeError,
228 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000229 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000230 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000231 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000232 if (timeout > (double)LONG_MAX) {
233 PyErr_SetString(PyExc_OverflowError, "timeout period too long");
234 return NULL;
235 }
236 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000237 timeout = timeout - (double)seconds;
238 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000239 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000240 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000241 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000242
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000243 /* sanity check first three arguments */
244 if (!PyList_Check(ifdlist) ||
245 !PyList_Check(ofdlist) ||
246 !PyList_Check(efdlist))
247 {
248 PyErr_SetString(PyExc_TypeError,
249 "arguments 1-3 must be lists");
250 return NULL;
251 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000252
Barry Warsawb44740f2001-08-16 16:52:59 +0000253#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000254 /* Allocate memory for the lists */
255 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
256 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
257 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
258 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000259 if (rfd2obj) PyMem_DEL(rfd2obj);
260 if (wfd2obj) PyMem_DEL(wfd2obj);
261 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000262 return NULL;
263 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000264#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000265 /* Convert lists to fd_sets, and get maximum fd number
266 * propagates the Python exception set in list2set()
267 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000268 rfd2obj[0].sentinel = -1;
269 wfd2obj[0].sentinel = -1;
270 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000271 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000272 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000273 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000274 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000275 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000276 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000277 max = imax;
278 if (omax > max) max = omax;
279 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000280
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000281 Py_BEGIN_ALLOW_THREADS
282 n = select(max, &ifdset, &ofdset, &efdset, tvp);
283 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000284
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000285 if (n < 0) {
286 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000287 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000288 else if (n == 0) {
289 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000290 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000291 if (ifdlist) {
292 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
293 Py_DECREF(ifdlist);
294 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000295 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000296 else {
297 /* any of these three calls can raise an exception. it's more
298 convenient to test for this after all three calls... but
299 is that acceptable?
300 */
301 ifdlist = set2list(&ifdset, rfd2obj);
302 ofdlist = set2list(&ofdset, wfd2obj);
303 efdlist = set2list(&efdset, efd2obj);
304 if (PyErr_Occurred())
305 ret = NULL;
306 else
307 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000308
Barry Warsawc1cb3601996-12-12 22:16:21 +0000309 Py_DECREF(ifdlist);
310 Py_DECREF(ofdlist);
311 Py_DECREF(efdlist);
312 }
313
314 finally:
315 reap_obj(rfd2obj);
316 reap_obj(wfd2obj);
317 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000318#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000319 PyMem_DEL(rfd2obj);
320 PyMem_DEL(wfd2obj);
321 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000322#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000323 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000324}
325
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000326#ifdef HAVE_POLL
327/*
328 * poll() support
329 */
330
331typedef struct {
332 PyObject_HEAD
333 PyObject *dict;
334 int ufd_uptodate;
335 int ufd_len;
336 struct pollfd *ufds;
337} pollObject;
338
339staticforward PyTypeObject poll_Type;
340
341/* Update the malloc'ed array of pollfds to match the dictionary
342 contained within a pollObject. Return 1 on success, 0 on an error.
343*/
344
345static int
346update_ufd_array(pollObject *self)
347{
Fred Drakedff3a372001-07-19 21:29:49 +0000348 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000349 PyObject *key, *value;
350
351 self->ufd_len = PyDict_Size(self->dict);
352 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
353 if (self->ufds == NULL) {
354 PyErr_NoMemory();
355 return 0;
356 }
357
358 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000359 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000360 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000361 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000362 i++;
363 }
364 self->ufd_uptodate = 1;
365 return 1;
366}
367
368static char poll_register_doc[] =
369"register(fd [, eventmask] ) -> None\n\n\
370Register a file descriptor with the polling object.\n\
371fd -- either an integer, or an object with a fileno() method returning an int.\n\
372events -- an optional bitmask describing the type of events to check for";
373
374static PyObject *
375poll_register(pollObject *self, PyObject *args)
376{
377 PyObject *o, *key, *value;
378 int fd, events = POLLIN | POLLPRI | POLLOUT;
379
Fred Drake7b87f852001-05-21 03:29:05 +0000380 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000381 return NULL;
382 }
383
384 fd = PyObject_AsFileDescriptor(o);
385 if (fd == -1) return NULL;
386
387 /* Add entry to the internal dictionary: the key is the
388 file descriptor, and the value is the event mask. */
389 if ( (NULL == (key = PyInt_FromLong(fd))) ||
390 (NULL == (value = PyInt_FromLong(events))) ||
391 (PyDict_SetItem(self->dict, key, value)) == -1) {
392 return NULL;
393 }
394 self->ufd_uptodate = 0;
395
396 Py_INCREF(Py_None);
397 return Py_None;
398}
399
400static char poll_unregister_doc[] =
401"unregister(fd) -> None\n\n\
402Remove a file descriptor being tracked by the polling object.";
403
404static PyObject *
405poll_unregister(pollObject *self, PyObject *args)
406{
407 PyObject *o, *key;
408 int fd;
409
Fred Drake7b87f852001-05-21 03:29:05 +0000410 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000411 return NULL;
412 }
413
414 fd = PyObject_AsFileDescriptor( o );
415 if (fd == -1)
416 return NULL;
417
418 /* Check whether the fd is already in the array */
419 key = PyInt_FromLong(fd);
420 if (key == NULL)
421 return NULL;
422
423 if (PyDict_DelItem(self->dict, key) == -1) {
424 Py_DECREF(key);
425 /* This will simply raise the KeyError set by PyDict_DelItem
426 if the file descriptor isn't registered. */
427 return NULL;
428 }
429
430 Py_DECREF(key);
431 self->ufd_uptodate = 0;
432
433 Py_INCREF(Py_None);
434 return Py_None;
435}
436
437static char poll_poll_doc[] =
438"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
439Polls the set of registered file descriptors, returning a list containing \n\
440any descriptors that have events or errors to report.";
441
442static PyObject *
443poll_poll(pollObject *self, PyObject *args)
444{
445 PyObject *result_list = NULL, *tout = NULL;
446 int timeout = 0, poll_result, i, j;
447 PyObject *value = NULL, *num = NULL;
448
Fred Drake7b87f852001-05-21 03:29:05 +0000449 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000450 return NULL;
451 }
452
453 /* Check values for timeout */
454 if (tout == NULL || tout == Py_None)
455 timeout = -1;
456 else if (!PyArg_Parse(tout, "i", &timeout)) {
457 PyErr_SetString(PyExc_TypeError,
458 "timeout must be an integer or None");
459 return NULL;
460 }
461
462 /* Ensure the ufd array is up to date */
463 if (!self->ufd_uptodate)
464 if (update_ufd_array(self) == 0)
465 return NULL;
466
467 /* call poll() */
468 Py_BEGIN_ALLOW_THREADS;
469 poll_result = poll(self->ufds, self->ufd_len, timeout);
470 Py_END_ALLOW_THREADS;
471
472 if (poll_result < 0) {
473 PyErr_SetFromErrno(SelectError);
474 return NULL;
475 }
476
477 /* build the result list */
478
479 result_list = PyList_New(poll_result);
480 if (!result_list)
481 return NULL;
482 else {
483 for (i = 0, j = 0; j < poll_result; j++) {
484 /* skip to the next fired descriptor */
485 while (!self->ufds[i].revents) {
486 i++;
487 }
488 /* if we hit a NULL return, set value to NULL
489 and break out of loop; code at end will
490 clean up result_list */
491 value = PyTuple_New(2);
492 if (value == NULL)
493 goto error;
494 num = PyInt_FromLong(self->ufds[i].fd);
495 if (num == NULL) {
496 Py_DECREF(value);
497 goto error;
498 }
499 PyTuple_SET_ITEM(value, 0, num);
500
501 num = PyInt_FromLong(self->ufds[i].revents);
502 if (num == NULL) {
503 Py_DECREF(value);
504 goto error;
505 }
506 PyTuple_SET_ITEM(value, 1, num);
507 if ((PyList_SetItem(result_list, j, value)) == -1) {
508 Py_DECREF(value);
509 goto error;
510 }
511 i++;
512 }
513 }
514 return result_list;
515
516 error:
517 Py_DECREF(result_list);
518 return NULL;
519}
520
521static PyMethodDef poll_methods[] = {
522 {"register", (PyCFunction)poll_register,
523 METH_VARARGS, poll_register_doc},
524 {"unregister", (PyCFunction)poll_unregister,
525 METH_VARARGS, poll_unregister_doc},
526 {"poll", (PyCFunction)poll_poll,
527 METH_VARARGS, poll_poll_doc},
528 {NULL, NULL} /* sentinel */
529};
530
531static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000532newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000533{
534 pollObject *self;
535 self = PyObject_New(pollObject, &poll_Type);
536 if (self == NULL)
537 return NULL;
538 /* ufd_uptodate is a Boolean, denoting whether the
539 array pointed to by ufds matches the contents of the dictionary. */
540 self->ufd_uptodate = 0;
541 self->ufds = NULL;
542 self->dict = PyDict_New();
543 if (self->dict == NULL) {
544 Py_DECREF(self);
545 return NULL;
546 }
547 return self;
548}
549
550static void
551poll_dealloc(pollObject *self)
552{
553 if (self->ufds != NULL)
554 PyMem_DEL(self->ufds);
555 Py_XDECREF(self->dict);
556 PyObject_Del(self);
557}
558
559static PyObject *
560poll_getattr(pollObject *self, char *name)
561{
562 return Py_FindMethod(poll_methods, (PyObject *)self, name);
563}
564
565statichere PyTypeObject poll_Type = {
566 /* The ob_type field must be initialized in the module init function
567 * to be portable to Windows without using C++. */
568 PyObject_HEAD_INIT(NULL)
569 0, /*ob_size*/
570 "poll", /*tp_name*/
571 sizeof(pollObject), /*tp_basicsize*/
572 0, /*tp_itemsize*/
573 /* methods */
574 (destructor)poll_dealloc, /*tp_dealloc*/
575 0, /*tp_print*/
576 (getattrfunc)poll_getattr, /*tp_getattr*/
577 0, /*tp_setattr*/
578 0, /*tp_compare*/
579 0, /*tp_repr*/
580 0, /*tp_as_number*/
581 0, /*tp_as_sequence*/
582 0, /*tp_as_mapping*/
583 0, /*tp_hash*/
584};
585
586static char poll_doc[] =
587"Returns a polling object, which supports registering and\n\
588unregistering file descriptors, and then polling them for I/O events.";
589
590static PyObject *
591select_poll(PyObject *self, PyObject *args)
592{
593 pollObject *rv;
594
595 if (!PyArg_ParseTuple(args, ":poll"))
596 return NULL;
597 rv = newPollObject();
598 if ( rv == NULL )
599 return NULL;
600 return (PyObject *)rv;
601}
602#endif /* HAVE_POLL */
603
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000604static char select_doc[] =
605"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
606\n\
607Wait until one or more file descriptors are ready for some kind of I/O.\n\
608The first three arguments are lists of file descriptors to be waited for:\n\
609rlist -- wait until ready for reading\n\
610wlist -- wait until ready for writing\n\
611xlist -- wait for an ``exceptional condition''\n\
612If only one kind of condition is required, pass [] for the other lists.\n\
613A file descriptor is either a socket or file object, or a small integer\n\
614gotten from a fileno() method call on one of those.\n\
615\n\
616The optional 4th argument specifies a timeout in seconds; it may be\n\
617a floating point number to specify fractions of seconds. If it is absent\n\
618or None, the call will never time out.\n\
619\n\
620The return value is a tuple of three lists corresponding to the first three\n\
621arguments; each contains the subset of the corresponding file descriptors\n\
622that are ready.\n\
623\n\
624*** IMPORTANT NOTICE ***\n\
625On Windows, only sockets are supported; on Unix, all file descriptors.";
626
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000627static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000628 {"select", select_select, METH_VARARGS, select_doc},
629#ifdef HAVE_POLL
630 {"poll", select_poll, METH_VARARGS, poll_doc},
631#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000632 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000633};
634
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000635static char module_doc[] =
636"This module supports asynchronous I/O on multiple file descriptors.\n\
637\n\
638*** IMPORTANT NOTICE ***\n\
639On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000640
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000641/*
642 * Convenience routine to export an integer value.
643 * For simplicity, errors (which are unlikely anyway) are ignored.
644 */
645
646static void
647insint(PyObject *d, char *name, int value)
648{
649 PyObject *v = PyInt_FromLong((long) value);
650 if (v == NULL) {
651 /* Don't bother reporting this error */
652 PyErr_Clear();
653 }
654 else {
655 PyDict_SetItemString(d, name, v);
656 Py_DECREF(v);
657 }
658}
659
Guido van Rossum3886bb61998-12-04 18:50:17 +0000660DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000661initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000662{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000663 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000664 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000665 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000666 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000667 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000668#ifdef HAVE_POLL
669 poll_Type.ob_type = &PyType_Type;
670 insint(d, "POLLIN", POLLIN);
671 insint(d, "POLLPRI", POLLPRI);
672 insint(d, "POLLOUT", POLLOUT);
673 insint(d, "POLLERR", POLLERR);
674 insint(d, "POLLHUP", POLLHUP);
675 insint(d, "POLLNVAL", POLLNVAL);
676
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000677#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000678 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000679#endif
680#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000681 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000682#endif
683#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000684 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000685#endif
686#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000687 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000688#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000689#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000690 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000691#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000692#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000693}