blob: fa34324f46d22472763fa7fff58d0c408e216319 [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) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000233 PyErr_SetString(PyExc_OverflowError,
234 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000235 return NULL;
236 }
237 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000238 timeout = timeout - (double)seconds;
239 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000240 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000241 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000242 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000243
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000244 /* sanity check first three arguments */
245 if (!PyList_Check(ifdlist) ||
246 !PyList_Check(ofdlist) ||
247 !PyList_Check(efdlist))
248 {
249 PyErr_SetString(PyExc_TypeError,
250 "arguments 1-3 must be lists");
251 return NULL;
252 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000253
Barry Warsawb44740f2001-08-16 16:52:59 +0000254#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000255 /* Allocate memory for the lists */
256 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
257 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
258 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
259 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000260 if (rfd2obj) PyMem_DEL(rfd2obj);
261 if (wfd2obj) PyMem_DEL(wfd2obj);
262 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000263 return NULL;
264 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000265#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000266 /* Convert lists to fd_sets, and get maximum fd number
267 * propagates the Python exception set in list2set()
268 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000269 rfd2obj[0].sentinel = -1;
270 wfd2obj[0].sentinel = -1;
271 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000272 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000273 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000275 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000276 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000277 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000278 max = imax;
279 if (omax > max) max = omax;
280 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000281
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000282 Py_BEGIN_ALLOW_THREADS
283 n = select(max, &ifdset, &ofdset, &efdset, tvp);
284 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000285
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000286 if (n < 0) {
287 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000288 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000289 else if (n == 0) {
290 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000291 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000292 if (ifdlist) {
293 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
294 Py_DECREF(ifdlist);
295 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000296 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000297 else {
298 /* any of these three calls can raise an exception. it's more
299 convenient to test for this after all three calls... but
300 is that acceptable?
301 */
302 ifdlist = set2list(&ifdset, rfd2obj);
303 ofdlist = set2list(&ofdset, wfd2obj);
304 efdlist = set2list(&efdset, efd2obj);
305 if (PyErr_Occurred())
306 ret = NULL;
307 else
308 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000309
Barry Warsawc1cb3601996-12-12 22:16:21 +0000310 Py_DECREF(ifdlist);
311 Py_DECREF(ofdlist);
312 Py_DECREF(efdlist);
313 }
314
315 finally:
316 reap_obj(rfd2obj);
317 reap_obj(wfd2obj);
318 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000319#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000320 PyMem_DEL(rfd2obj);
321 PyMem_DEL(wfd2obj);
322 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000323#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000324 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000325}
326
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000327#ifdef HAVE_POLL
328/*
329 * poll() support
330 */
331
332typedef struct {
333 PyObject_HEAD
334 PyObject *dict;
335 int ufd_uptodate;
336 int ufd_len;
337 struct pollfd *ufds;
338} pollObject;
339
340staticforward PyTypeObject poll_Type;
341
342/* Update the malloc'ed array of pollfds to match the dictionary
343 contained within a pollObject. Return 1 on success, 0 on an error.
344*/
345
346static int
347update_ufd_array(pollObject *self)
348{
Fred Drakedff3a372001-07-19 21:29:49 +0000349 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000350 PyObject *key, *value;
351
352 self->ufd_len = PyDict_Size(self->dict);
353 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
354 if (self->ufds == NULL) {
355 PyErr_NoMemory();
356 return 0;
357 }
358
359 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000360 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000361 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000362 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000363 i++;
364 }
365 self->ufd_uptodate = 1;
366 return 1;
367}
368
369static char poll_register_doc[] =
370"register(fd [, eventmask] ) -> None\n\n\
371Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000372fd -- either an integer, or an object with a fileno() method returning an\n\
373 int.\n\
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000374events -- an optional bitmask describing the type of events to check for";
375
376static PyObject *
377poll_register(pollObject *self, PyObject *args)
378{
379 PyObject *o, *key, *value;
380 int fd, events = POLLIN | POLLPRI | POLLOUT;
381
Fred Drake7b87f852001-05-21 03:29:05 +0000382 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000383 return NULL;
384 }
385
386 fd = PyObject_AsFileDescriptor(o);
387 if (fd == -1) return NULL;
388
389 /* Add entry to the internal dictionary: the key is the
390 file descriptor, and the value is the event mask. */
391 if ( (NULL == (key = PyInt_FromLong(fd))) ||
392 (NULL == (value = PyInt_FromLong(events))) ||
393 (PyDict_SetItem(self->dict, key, value)) == -1) {
394 return NULL;
395 }
396 self->ufd_uptodate = 0;
397
398 Py_INCREF(Py_None);
399 return Py_None;
400}
401
402static char poll_unregister_doc[] =
403"unregister(fd) -> None\n\n\
404Remove a file descriptor being tracked by the polling object.";
405
406static PyObject *
407poll_unregister(pollObject *self, PyObject *args)
408{
409 PyObject *o, *key;
410 int fd;
411
Fred Drake7b87f852001-05-21 03:29:05 +0000412 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000413 return NULL;
414 }
415
416 fd = PyObject_AsFileDescriptor( o );
417 if (fd == -1)
418 return NULL;
419
420 /* Check whether the fd is already in the array */
421 key = PyInt_FromLong(fd);
422 if (key == NULL)
423 return NULL;
424
425 if (PyDict_DelItem(self->dict, key) == -1) {
426 Py_DECREF(key);
427 /* This will simply raise the KeyError set by PyDict_DelItem
428 if the file descriptor isn't registered. */
429 return NULL;
430 }
431
432 Py_DECREF(key);
433 self->ufd_uptodate = 0;
434
435 Py_INCREF(Py_None);
436 return Py_None;
437}
438
439static char poll_poll_doc[] =
440"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
441Polls the set of registered file descriptors, returning a list containing \n\
442any descriptors that have events or errors to report.";
443
444static PyObject *
445poll_poll(pollObject *self, PyObject *args)
446{
447 PyObject *result_list = NULL, *tout = NULL;
448 int timeout = 0, poll_result, i, j;
449 PyObject *value = NULL, *num = NULL;
450
Fred Drake7b87f852001-05-21 03:29:05 +0000451 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000452 return NULL;
453 }
454
455 /* Check values for timeout */
456 if (tout == NULL || tout == Py_None)
457 timeout = -1;
458 else if (!PyArg_Parse(tout, "i", &timeout)) {
459 PyErr_SetString(PyExc_TypeError,
460 "timeout must be an integer or None");
461 return NULL;
462 }
463
464 /* Ensure the ufd array is up to date */
465 if (!self->ufd_uptodate)
466 if (update_ufd_array(self) == 0)
467 return NULL;
468
469 /* call poll() */
470 Py_BEGIN_ALLOW_THREADS;
471 poll_result = poll(self->ufds, self->ufd_len, timeout);
472 Py_END_ALLOW_THREADS;
473
474 if (poll_result < 0) {
475 PyErr_SetFromErrno(SelectError);
476 return NULL;
477 }
478
479 /* build the result list */
480
481 result_list = PyList_New(poll_result);
482 if (!result_list)
483 return NULL;
484 else {
485 for (i = 0, j = 0; j < poll_result; j++) {
486 /* skip to the next fired descriptor */
487 while (!self->ufds[i].revents) {
488 i++;
489 }
490 /* if we hit a NULL return, set value to NULL
491 and break out of loop; code at end will
492 clean up result_list */
493 value = PyTuple_New(2);
494 if (value == NULL)
495 goto error;
496 num = PyInt_FromLong(self->ufds[i].fd);
497 if (num == NULL) {
498 Py_DECREF(value);
499 goto error;
500 }
501 PyTuple_SET_ITEM(value, 0, num);
502
503 num = PyInt_FromLong(self->ufds[i].revents);
504 if (num == NULL) {
505 Py_DECREF(value);
506 goto error;
507 }
508 PyTuple_SET_ITEM(value, 1, num);
509 if ((PyList_SetItem(result_list, j, value)) == -1) {
510 Py_DECREF(value);
511 goto error;
512 }
513 i++;
514 }
515 }
516 return result_list;
517
518 error:
519 Py_DECREF(result_list);
520 return NULL;
521}
522
523static PyMethodDef poll_methods[] = {
524 {"register", (PyCFunction)poll_register,
525 METH_VARARGS, poll_register_doc},
526 {"unregister", (PyCFunction)poll_unregister,
527 METH_VARARGS, poll_unregister_doc},
528 {"poll", (PyCFunction)poll_poll,
529 METH_VARARGS, poll_poll_doc},
530 {NULL, NULL} /* sentinel */
531};
532
533static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000534newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000535{
536 pollObject *self;
537 self = PyObject_New(pollObject, &poll_Type);
538 if (self == NULL)
539 return NULL;
540 /* ufd_uptodate is a Boolean, denoting whether the
541 array pointed to by ufds matches the contents of the dictionary. */
542 self->ufd_uptodate = 0;
543 self->ufds = NULL;
544 self->dict = PyDict_New();
545 if (self->dict == NULL) {
546 Py_DECREF(self);
547 return NULL;
548 }
549 return self;
550}
551
552static void
553poll_dealloc(pollObject *self)
554{
555 if (self->ufds != NULL)
556 PyMem_DEL(self->ufds);
557 Py_XDECREF(self->dict);
558 PyObject_Del(self);
559}
560
561static PyObject *
562poll_getattr(pollObject *self, char *name)
563{
564 return Py_FindMethod(poll_methods, (PyObject *)self, name);
565}
566
567statichere PyTypeObject poll_Type = {
568 /* The ob_type field must be initialized in the module init function
569 * to be portable to Windows without using C++. */
570 PyObject_HEAD_INIT(NULL)
571 0, /*ob_size*/
572 "poll", /*tp_name*/
573 sizeof(pollObject), /*tp_basicsize*/
574 0, /*tp_itemsize*/
575 /* methods */
576 (destructor)poll_dealloc, /*tp_dealloc*/
577 0, /*tp_print*/
578 (getattrfunc)poll_getattr, /*tp_getattr*/
579 0, /*tp_setattr*/
580 0, /*tp_compare*/
581 0, /*tp_repr*/
582 0, /*tp_as_number*/
583 0, /*tp_as_sequence*/
584 0, /*tp_as_mapping*/
585 0, /*tp_hash*/
586};
587
588static char poll_doc[] =
589"Returns a polling object, which supports registering and\n\
590unregistering file descriptors, and then polling them for I/O events.";
591
592static PyObject *
593select_poll(PyObject *self, PyObject *args)
594{
595 pollObject *rv;
596
597 if (!PyArg_ParseTuple(args, ":poll"))
598 return NULL;
599 rv = newPollObject();
600 if ( rv == NULL )
601 return NULL;
602 return (PyObject *)rv;
603}
604#endif /* HAVE_POLL */
605
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000606static char select_doc[] =
607"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
608\n\
609Wait until one or more file descriptors are ready for some kind of I/O.\n\
610The first three arguments are lists of file descriptors to be waited for:\n\
611rlist -- wait until ready for reading\n\
612wlist -- wait until ready for writing\n\
613xlist -- wait for an ``exceptional condition''\n\
614If only one kind of condition is required, pass [] for the other lists.\n\
615A file descriptor is either a socket or file object, or a small integer\n\
616gotten from a fileno() method call on one of those.\n\
617\n\
618The optional 4th argument specifies a timeout in seconds; it may be\n\
619a floating point number to specify fractions of seconds. If it is absent\n\
620or None, the call will never time out.\n\
621\n\
622The return value is a tuple of three lists corresponding to the first three\n\
623arguments; each contains the subset of the corresponding file descriptors\n\
624that are ready.\n\
625\n\
626*** IMPORTANT NOTICE ***\n\
627On Windows, only sockets are supported; on Unix, all file descriptors.";
628
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000629static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000630 {"select", select_select, METH_VARARGS, select_doc},
631#ifdef HAVE_POLL
632 {"poll", select_poll, METH_VARARGS, poll_doc},
633#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000634 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000635};
636
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000637static char module_doc[] =
638"This module supports asynchronous I/O on multiple file descriptors.\n\
639\n\
640*** IMPORTANT NOTICE ***\n\
641On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000642
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000643/*
644 * Convenience routine to export an integer value.
645 * For simplicity, errors (which are unlikely anyway) are ignored.
646 */
647
648static void
649insint(PyObject *d, char *name, int value)
650{
651 PyObject *v = PyInt_FromLong((long) value);
652 if (v == NULL) {
653 /* Don't bother reporting this error */
654 PyErr_Clear();
655 }
656 else {
657 PyDict_SetItemString(d, name, v);
658 Py_DECREF(v);
659 }
660}
661
Guido van Rossum3886bb61998-12-04 18:50:17 +0000662DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000663initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000664{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000665 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000666 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000667 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000668 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000669 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000670#ifdef HAVE_POLL
671 poll_Type.ob_type = &PyType_Type;
672 insint(d, "POLLIN", POLLIN);
673 insint(d, "POLLPRI", POLLPRI);
674 insint(d, "POLLOUT", POLLOUT);
675 insint(d, "POLLERR", POLLERR);
676 insint(d, "POLLHUP", POLLHUP);
677 insint(d, "POLLNVAL", POLLNVAL);
678
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000679#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000680 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000681#endif
682#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000683 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000684#endif
685#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000686 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000687#endif
688#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000689 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000690#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000691#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000692 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000693#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000694#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000695}