blob: 55c3a49c5359a19f631d967e362bb82ae2a1c7a0 [file] [log] [blame]
Guido van Rossumed233a51992-06-23 09:07:03 +00001
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00002/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +00003 Under Unix, the file descriptors are small integers.
4 Under Win32, select only exists for sockets, and sockets may
5 have any value except INVALID_SOCKET.
Guido van Rossumbcc20741998-08-04 22:53:56 +00006 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
7 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +00008*/
Guido van Rossumed233a51992-06-23 09:07:03 +00009
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000010#include "Python.h"
Guido van Rossumed233a51992-06-23 09:07:03 +000011
Guido van Rossuma376cc51996-12-05 23:43:35 +000012#ifdef HAVE_UNISTD_H
13#include <unistd.h>
14#endif
Jack Jansene4b48632000-07-11 21:35:02 +000015#ifdef HAVE_LIMITS_H
16#include <limits.h>
17#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000018#ifdef HAVE_POLL_H
19#include <poll.h>
20#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000021
Guido van Rossum37273171996-12-09 18:47:43 +000022#ifdef __sgi
23/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000024extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000025#endif
26
Guido van Rossumff7e83d1999-08-27 20:39:37 +000027#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000028#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000029#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000030
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000031#if defined(PYOS_OS2)
32#include <sys/time.h>
33#include <utils.h>
34#endif
35
Guido van Rossum6f489d91996-06-28 20:15:15 +000036#ifdef MS_WINDOWS
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000037#include <winsock.h>
38#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000039#ifdef __BEOS__
40#include <net/socket.h>
41#define SOCKET int
42#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000043#define SOCKET int
44#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000045#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000046
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000047static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000048
Barry Warsawc1cb3601996-12-12 22:16:21 +000049/* list of Python objects and their file descriptor */
50typedef struct {
51 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000052 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000053 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000054} pylist;
55
Barry Warsawc1cb3601996-12-12 22:16:21 +000056static void
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000057reap_obj(pylist fd2obj[FD_SETSIZE + 3])
Barry Warsawc1cb3601996-12-12 22:16:21 +000058{
59 int i;
60 for (i = 0; i < FD_SETSIZE + 3 && fd2obj[i].sentinel >= 0; i++) {
61 Py_XDECREF(fd2obj[i].obj);
62 fd2obj[i].obj = NULL;
63 }
64 fd2obj[0].sentinel = -1;
65}
66
67
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000068/* returns -1 and sets the Python exception if an error occurred, otherwise
69 returns a number >= 0
70*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000071static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000072list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +000073{
Barry Warsawc1cb3601996-12-12 22:16:21 +000074 int i;
75 int max = -1;
76 int index = 0;
77 int len = PyList_Size(list);
78 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000079
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000080 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000081 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000082
83 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000084 SOCKET v;
85
86 /* any intervening fileno() calls could decr this refcnt */
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000087 if (!(o = PyList_GetItem(list, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +000088 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000089
Barry Warsawc1cb3601996-12-12 22:16:21 +000090 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +000091 v = PyObject_AsFileDescriptor( o );
92 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +000093
Guido van Rossum947a0fa2000-01-14 16:33:09 +000094#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +000095 max = 0; /* not used for Win32 */
96#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000097 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000098 PyErr_SetString(PyExc_ValueError,
99 "filedescriptor out of range in select()");
100 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000101 }
102 if (v > max)
103 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000105 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000106
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000107 /* add object and its file descriptor to the list */
108 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000109 PyErr_SetString(PyExc_ValueError,
110 "too many file descriptors in select()");
111 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000112 }
113 fd2obj[index].obj = o;
114 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115 fd2obj[index].sentinel = 0;
116 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000117 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000118 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000119
120 finally:
121 Py_XDECREF(o);
122 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000123}
124
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000125/* returns NULL and sets the Python exception if an error occurred */
126static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000127set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +0000128{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000129 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000130 PyObject *list, *o;
131 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000132
Barry Warsawc1cb3601996-12-12 22:16:21 +0000133 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000134 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000135 count++;
136 }
137 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000138 if (!list)
139 return NULL;
140
Barry Warsawc1cb3601996-12-12 22:16:21 +0000141 i = 0;
142 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143 fd = fd2obj[j].fd;
144 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000145#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000146 if (fd > FD_SETSIZE) {
147 PyErr_SetString(PyExc_SystemError,
148 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000149 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000150 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000151#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000152 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000153 fd2obj[j].obj = NULL;
154 /* transfer ownership */
155 if (PyList_SetItem(list, i, o) < 0)
156 goto finally;
157
158 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159 }
160 }
161 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000162 finally:
163 Py_DECREF(list);
164 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000165}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000166
Guido van Rossumed233a51992-06-23 09:07:03 +0000167
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000168static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000169select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000170{
Guido van Rossumd20781b1998-07-02 02:53:36 +0000171#ifdef MS_WINDOWS
172 /* This would be an awful lot of stack space on Windows! */
173 pylist *rfd2obj, *wfd2obj, *efd2obj;
174#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000175 pylist rfd2obj[FD_SETSIZE + 3];
176 pylist wfd2obj[FD_SETSIZE + 3];
177 pylist efd2obj[FD_SETSIZE + 3];
Guido van Rossumd20781b1998-07-02 02:53:36 +0000178#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000179 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000180 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000181 PyObject *tout = Py_None;
182 fd_set ifdset, ofdset, efdset;
183 double timeout;
184 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000185 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000186 int imax, omax, emax, max;
187 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000188
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000189 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000190 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000191 &ifdlist, &ofdlist, &efdlist, &tout))
192 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000193
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000194 if (tout == Py_None)
195 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000196 else if (!PyArg_Parse(tout, "d", &timeout)) {
197 PyErr_SetString(PyExc_TypeError,
198 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000199 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000200 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000201 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000202 if (timeout > (double)LONG_MAX) {
203 PyErr_SetString(PyExc_OverflowError, "timeout period too long");
204 return NULL;
205 }
206 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000207 timeout = timeout - (double)seconds;
208 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000209 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000210 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000211 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000212
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000213 /* sanity check first three arguments */
214 if (!PyList_Check(ifdlist) ||
215 !PyList_Check(ofdlist) ||
216 !PyList_Check(efdlist))
217 {
218 PyErr_SetString(PyExc_TypeError,
219 "arguments 1-3 must be lists");
220 return NULL;
221 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000222
Guido van Rossumd20781b1998-07-02 02:53:36 +0000223#ifdef MS_WINDOWS
224 /* Allocate memory for the lists */
225 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
226 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
227 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
228 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000229 if (rfd2obj) PyMem_DEL(rfd2obj);
230 if (wfd2obj) PyMem_DEL(wfd2obj);
231 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000232 return NULL;
233 }
234#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000235 /* Convert lists to fd_sets, and get maximum fd number
236 * propagates the Python exception set in list2set()
237 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000238 rfd2obj[0].sentinel = -1;
239 wfd2obj[0].sentinel = -1;
240 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000241 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000242 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000243 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000244 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000245 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000246 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000247 max = imax;
248 if (omax > max) max = omax;
249 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000250
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000251 Py_BEGIN_ALLOW_THREADS
252 n = select(max, &ifdset, &ofdset, &efdset, tvp);
253 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000254
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000255 if (n < 0) {
256 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000257 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000258 else if (n == 0) {
259 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000260 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000261 if (ifdlist) {
262 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
263 Py_DECREF(ifdlist);
264 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000265 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000266 else {
267 /* any of these three calls can raise an exception. it's more
268 convenient to test for this after all three calls... but
269 is that acceptable?
270 */
271 ifdlist = set2list(&ifdset, rfd2obj);
272 ofdlist = set2list(&ofdset, wfd2obj);
273 efdlist = set2list(&efdset, efd2obj);
274 if (PyErr_Occurred())
275 ret = NULL;
276 else
277 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000278
Barry Warsawc1cb3601996-12-12 22:16:21 +0000279 Py_DECREF(ifdlist);
280 Py_DECREF(ofdlist);
281 Py_DECREF(efdlist);
282 }
283
284 finally:
285 reap_obj(rfd2obj);
286 reap_obj(wfd2obj);
287 reap_obj(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000288#ifdef MS_WINDOWS
289 PyMem_DEL(rfd2obj);
290 PyMem_DEL(wfd2obj);
291 PyMem_DEL(efd2obj);
292#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000293 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000294}
295
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000296#ifdef HAVE_POLL
297/*
298 * poll() support
299 */
300
301typedef struct {
302 PyObject_HEAD
303 PyObject *dict;
304 int ufd_uptodate;
305 int ufd_len;
306 struct pollfd *ufds;
307} pollObject;
308
309staticforward PyTypeObject poll_Type;
310
311/* Update the malloc'ed array of pollfds to match the dictionary
312 contained within a pollObject. Return 1 on success, 0 on an error.
313*/
314
315static int
316update_ufd_array(pollObject *self)
317{
318 int i, j, pos;
319 PyObject *key, *value;
320
321 self->ufd_len = PyDict_Size(self->dict);
322 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
323 if (self->ufds == NULL) {
324 PyErr_NoMemory();
325 return 0;
326 }
327
328 i = pos = 0;
329 while ((j = PyDict_Next(self->dict, &pos, &key, &value))) {
330 self->ufds[i].fd = PyInt_AsLong(key);
331 self->ufds[i].events = PyInt_AsLong(value);
332 i++;
333 }
334 self->ufd_uptodate = 1;
335 return 1;
336}
337
338static char poll_register_doc[] =
339"register(fd [, eventmask] ) -> None\n\n\
340Register a file descriptor with the polling object.\n\
341fd -- either an integer, or an object with a fileno() method returning an int.\n\
342events -- an optional bitmask describing the type of events to check for";
343
344static PyObject *
345poll_register(pollObject *self, PyObject *args)
346{
347 PyObject *o, *key, *value;
348 int fd, events = POLLIN | POLLPRI | POLLOUT;
349
350 if (!PyArg_ParseTuple(args, "O|i", &o, &events)) {
351 return NULL;
352 }
353
354 fd = PyObject_AsFileDescriptor(o);
355 if (fd == -1) return NULL;
356
357 /* Add entry to the internal dictionary: the key is the
358 file descriptor, and the value is the event mask. */
359 if ( (NULL == (key = PyInt_FromLong(fd))) ||
360 (NULL == (value = PyInt_FromLong(events))) ||
361 (PyDict_SetItem(self->dict, key, value)) == -1) {
362 return NULL;
363 }
364 self->ufd_uptodate = 0;
365
366 Py_INCREF(Py_None);
367 return Py_None;
368}
369
370static char poll_unregister_doc[] =
371"unregister(fd) -> None\n\n\
372Remove a file descriptor being tracked by the polling object.";
373
374static PyObject *
375poll_unregister(pollObject *self, PyObject *args)
376{
377 PyObject *o, *key;
378 int fd;
379
380 if (!PyArg_ParseTuple(args, "O", &o)) {
381 return NULL;
382 }
383
384 fd = PyObject_AsFileDescriptor( o );
385 if (fd == -1)
386 return NULL;
387
388 /* Check whether the fd is already in the array */
389 key = PyInt_FromLong(fd);
390 if (key == NULL)
391 return NULL;
392
393 if (PyDict_DelItem(self->dict, key) == -1) {
394 Py_DECREF(key);
395 /* This will simply raise the KeyError set by PyDict_DelItem
396 if the file descriptor isn't registered. */
397 return NULL;
398 }
399
400 Py_DECREF(key);
401 self->ufd_uptodate = 0;
402
403 Py_INCREF(Py_None);
404 return Py_None;
405}
406
407static char poll_poll_doc[] =
408"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
409Polls the set of registered file descriptors, returning a list containing \n\
410any descriptors that have events or errors to report.";
411
412static PyObject *
413poll_poll(pollObject *self, PyObject *args)
414{
415 PyObject *result_list = NULL, *tout = NULL;
416 int timeout = 0, poll_result, i, j;
417 PyObject *value = NULL, *num = NULL;
418
419 if (!PyArg_ParseTuple(args, "|O", &tout)) {
420 return NULL;
421 }
422
423 /* Check values for timeout */
424 if (tout == NULL || tout == Py_None)
425 timeout = -1;
426 else if (!PyArg_Parse(tout, "i", &timeout)) {
427 PyErr_SetString(PyExc_TypeError,
428 "timeout must be an integer or None");
429 return NULL;
430 }
431
432 /* Ensure the ufd array is up to date */
433 if (!self->ufd_uptodate)
434 if (update_ufd_array(self) == 0)
435 return NULL;
436
437 /* call poll() */
438 Py_BEGIN_ALLOW_THREADS;
439 poll_result = poll(self->ufds, self->ufd_len, timeout);
440 Py_END_ALLOW_THREADS;
441
442 if (poll_result < 0) {
443 PyErr_SetFromErrno(SelectError);
444 return NULL;
445 }
446
447 /* build the result list */
448
449 result_list = PyList_New(poll_result);
450 if (!result_list)
451 return NULL;
452 else {
453 for (i = 0, j = 0; j < poll_result; j++) {
454 /* skip to the next fired descriptor */
455 while (!self->ufds[i].revents) {
456 i++;
457 }
458 /* if we hit a NULL return, set value to NULL
459 and break out of loop; code at end will
460 clean up result_list */
461 value = PyTuple_New(2);
462 if (value == NULL)
463 goto error;
464 num = PyInt_FromLong(self->ufds[i].fd);
465 if (num == NULL) {
466 Py_DECREF(value);
467 goto error;
468 }
469 PyTuple_SET_ITEM(value, 0, num);
470
471 num = PyInt_FromLong(self->ufds[i].revents);
472 if (num == NULL) {
473 Py_DECREF(value);
474 goto error;
475 }
476 PyTuple_SET_ITEM(value, 1, num);
477 if ((PyList_SetItem(result_list, j, value)) == -1) {
478 Py_DECREF(value);
479 goto error;
480 }
481 i++;
482 }
483 }
484 return result_list;
485
486 error:
487 Py_DECREF(result_list);
488 return NULL;
489}
490
491static PyMethodDef poll_methods[] = {
492 {"register", (PyCFunction)poll_register,
493 METH_VARARGS, poll_register_doc},
494 {"unregister", (PyCFunction)poll_unregister,
495 METH_VARARGS, poll_unregister_doc},
496 {"poll", (PyCFunction)poll_poll,
497 METH_VARARGS, poll_poll_doc},
498 {NULL, NULL} /* sentinel */
499};
500
501static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000502newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000503{
504 pollObject *self;
505 self = PyObject_New(pollObject, &poll_Type);
506 if (self == NULL)
507 return NULL;
508 /* ufd_uptodate is a Boolean, denoting whether the
509 array pointed to by ufds matches the contents of the dictionary. */
510 self->ufd_uptodate = 0;
511 self->ufds = NULL;
512 self->dict = PyDict_New();
513 if (self->dict == NULL) {
514 Py_DECREF(self);
515 return NULL;
516 }
517 return self;
518}
519
520static void
521poll_dealloc(pollObject *self)
522{
523 if (self->ufds != NULL)
524 PyMem_DEL(self->ufds);
525 Py_XDECREF(self->dict);
526 PyObject_Del(self);
527}
528
529static PyObject *
530poll_getattr(pollObject *self, char *name)
531{
532 return Py_FindMethod(poll_methods, (PyObject *)self, name);
533}
534
535statichere PyTypeObject poll_Type = {
536 /* The ob_type field must be initialized in the module init function
537 * to be portable to Windows without using C++. */
538 PyObject_HEAD_INIT(NULL)
539 0, /*ob_size*/
540 "poll", /*tp_name*/
541 sizeof(pollObject), /*tp_basicsize*/
542 0, /*tp_itemsize*/
543 /* methods */
544 (destructor)poll_dealloc, /*tp_dealloc*/
545 0, /*tp_print*/
546 (getattrfunc)poll_getattr, /*tp_getattr*/
547 0, /*tp_setattr*/
548 0, /*tp_compare*/
549 0, /*tp_repr*/
550 0, /*tp_as_number*/
551 0, /*tp_as_sequence*/
552 0, /*tp_as_mapping*/
553 0, /*tp_hash*/
554};
555
556static char poll_doc[] =
557"Returns a polling object, which supports registering and\n\
558unregistering file descriptors, and then polling them for I/O events.";
559
560static PyObject *
561select_poll(PyObject *self, PyObject *args)
562{
563 pollObject *rv;
564
565 if (!PyArg_ParseTuple(args, ":poll"))
566 return NULL;
567 rv = newPollObject();
568 if ( rv == NULL )
569 return NULL;
570 return (PyObject *)rv;
571}
572#endif /* HAVE_POLL */
573
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000574static char select_doc[] =
575"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
576\n\
577Wait until one or more file descriptors are ready for some kind of I/O.\n\
578The first three arguments are lists of file descriptors to be waited for:\n\
579rlist -- wait until ready for reading\n\
580wlist -- wait until ready for writing\n\
581xlist -- wait for an ``exceptional condition''\n\
582If only one kind of condition is required, pass [] for the other lists.\n\
583A file descriptor is either a socket or file object, or a small integer\n\
584gotten from a fileno() method call on one of those.\n\
585\n\
586The optional 4th argument specifies a timeout in seconds; it may be\n\
587a floating point number to specify fractions of seconds. If it is absent\n\
588or None, the call will never time out.\n\
589\n\
590The return value is a tuple of three lists corresponding to the first three\n\
591arguments; each contains the subset of the corresponding file descriptors\n\
592that are ready.\n\
593\n\
594*** IMPORTANT NOTICE ***\n\
595On Windows, only sockets are supported; on Unix, all file descriptors.";
596
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000597static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000598 {"select", select_select, METH_VARARGS, select_doc},
599#ifdef HAVE_POLL
600 {"poll", select_poll, METH_VARARGS, poll_doc},
601#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000602 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000603};
604
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000605static char module_doc[] =
606"This module supports asynchronous I/O on multiple file descriptors.\n\
607\n\
608*** IMPORTANT NOTICE ***\n\
609On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000610
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000611/*
612 * Convenience routine to export an integer value.
613 * For simplicity, errors (which are unlikely anyway) are ignored.
614 */
615
616static void
617insint(PyObject *d, char *name, int value)
618{
619 PyObject *v = PyInt_FromLong((long) value);
620 if (v == NULL) {
621 /* Don't bother reporting this error */
622 PyErr_Clear();
623 }
624 else {
625 PyDict_SetItemString(d, name, v);
626 Py_DECREF(v);
627 }
628}
629
Guido van Rossum3886bb61998-12-04 18:50:17 +0000630DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000631initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000632{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000633 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000634 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000635 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000636 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000637 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000638#ifdef HAVE_POLL
639 poll_Type.ob_type = &PyType_Type;
640 insint(d, "POLLIN", POLLIN);
641 insint(d, "POLLPRI", POLLPRI);
642 insint(d, "POLLOUT", POLLOUT);
643 insint(d, "POLLERR", POLLERR);
644 insint(d, "POLLHUP", POLLHUP);
645 insint(d, "POLLNVAL", POLLNVAL);
646
647 insint(d, "POLLRDNORM", POLLRDNORM);
648 insint(d, "POLLRDBAND", POLLRDBAND);
649 insint(d, "POLLWRNORM", POLLWRNORM);
650 insint(d, "POLLWRBAND", POLLWRBAND);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000651#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000652 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000653#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000654#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000655}