blob: 114ac35fb7ab751d736271d34f90e45ddffeaf0b [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
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000015#ifdef HAVE_POLL_H
16#include <poll.h>
17#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000018
Guido van Rossum37273171996-12-09 18:47:43 +000019#ifdef __sgi
20/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000021extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000022#endif
23
Guido van Rossumff7e83d1999-08-27 20:39:37 +000024#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000025#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000026#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000027
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000028#if defined(PYOS_OS2)
29#include <sys/time.h>
30#include <utils.h>
31#endif
32
Guido van Rossum6f489d91996-06-28 20:15:15 +000033#ifdef MS_WINDOWS
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000034#include <winsock.h>
35#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000036#ifdef __BEOS__
37#include <net/socket.h>
38#define SOCKET int
39#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000040#define SOCKET int
41#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000042#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000043
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000044static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000045
Barry Warsawc1cb3601996-12-12 22:16:21 +000046/* list of Python objects and their file descriptor */
47typedef struct {
48 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000049 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000050 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000051} pylist;
52
Barry Warsawc1cb3601996-12-12 22:16:21 +000053static void
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000054reap_obj(pylist fd2obj[FD_SETSIZE + 3])
Barry Warsawc1cb3601996-12-12 22:16:21 +000055{
56 int i;
57 for (i = 0; i < FD_SETSIZE + 3 && fd2obj[i].sentinel >= 0; i++) {
58 Py_XDECREF(fd2obj[i].obj);
59 fd2obj[i].obj = NULL;
60 }
61 fd2obj[0].sentinel = -1;
62}
63
64
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000065/* returns -1 and sets the Python exception if an error occurred, otherwise
66 returns a number >= 0
67*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000068static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000069list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +000070{
Barry Warsawc1cb3601996-12-12 22:16:21 +000071 int i;
72 int max = -1;
73 int index = 0;
74 int len = PyList_Size(list);
75 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000076
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000077 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000078 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000079
80 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000081 SOCKET v;
82
83 /* any intervening fileno() calls could decr this refcnt */
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000084 if (!(o = PyList_GetItem(list, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +000085 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000086
Barry Warsawc1cb3601996-12-12 22:16:21 +000087 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +000088 v = PyObject_AsFileDescriptor( o );
89 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +000090
Guido van Rossum947a0fa2000-01-14 16:33:09 +000091#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +000092 max = 0; /* not used for Win32 */
93#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000094 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000095 PyErr_SetString(PyExc_ValueError,
96 "filedescriptor out of range in select()");
97 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000098 }
99 if (v > max)
100 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000101#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000102 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000103
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000104 /* add object and its file descriptor to the list */
105 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000106 PyErr_SetString(PyExc_ValueError,
107 "too many file descriptors in select()");
108 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000109 }
110 fd2obj[index].obj = o;
111 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000112 fd2obj[index].sentinel = 0;
113 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000114 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000115 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000116
117 finally:
118 Py_XDECREF(o);
119 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000120}
121
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000122/* returns NULL and sets the Python exception if an error occurred */
123static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000124set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +0000125{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000126 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000127 PyObject *list, *o;
128 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000129
Barry Warsawc1cb3601996-12-12 22:16:21 +0000130 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000131 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000132 count++;
133 }
134 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000135 if (!list)
136 return NULL;
137
Barry Warsawc1cb3601996-12-12 22:16:21 +0000138 i = 0;
139 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000140 fd = fd2obj[j].fd;
141 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000142#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143 if (fd > FD_SETSIZE) {
144 PyErr_SetString(PyExc_SystemError,
145 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000146 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000147 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000148#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000149 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000150 fd2obj[j].obj = NULL;
151 /* transfer ownership */
152 if (PyList_SetItem(list, i, o) < 0)
153 goto finally;
154
155 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000156 }
157 }
158 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000159 finally:
160 Py_DECREF(list);
161 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000162}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000163
Guido van Rossumed233a51992-06-23 09:07:03 +0000164
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000165static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000166select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000167{
Guido van Rossumd20781b1998-07-02 02:53:36 +0000168#ifdef MS_WINDOWS
169 /* This would be an awful lot of stack space on Windows! */
170 pylist *rfd2obj, *wfd2obj, *efd2obj;
171#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000172 pylist rfd2obj[FD_SETSIZE + 3];
173 pylist wfd2obj[FD_SETSIZE + 3];
174 pylist efd2obj[FD_SETSIZE + 3];
Guido van Rossumd20781b1998-07-02 02:53:36 +0000175#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000176 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000177 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000178 PyObject *tout = Py_None;
179 fd_set ifdset, ofdset, efdset;
180 double timeout;
181 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000182 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000183 int imax, omax, emax, max;
184 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000185
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000186 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000187 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000188 &ifdlist, &ofdlist, &efdlist, &tout))
189 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000190
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000191 if (tout == Py_None)
192 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000193 else if (!PyArg_Parse(tout, "d", &timeout)) {
194 PyErr_SetString(PyExc_TypeError,
195 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000196 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000197 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000198 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000199 if (timeout > (double)LONG_MAX) {
200 PyErr_SetString(PyExc_OverflowError, "timeout period too long");
201 return NULL;
202 }
203 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000204 timeout = timeout - (double)seconds;
205 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000206 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000207 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000208 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000209
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000210 /* sanity check first three arguments */
211 if (!PyList_Check(ifdlist) ||
212 !PyList_Check(ofdlist) ||
213 !PyList_Check(efdlist))
214 {
215 PyErr_SetString(PyExc_TypeError,
216 "arguments 1-3 must be lists");
217 return NULL;
218 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000219
Guido van Rossumd20781b1998-07-02 02:53:36 +0000220#ifdef MS_WINDOWS
221 /* Allocate memory for the lists */
222 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
223 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
224 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
225 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000226 if (rfd2obj) PyMem_DEL(rfd2obj);
227 if (wfd2obj) PyMem_DEL(wfd2obj);
228 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000229 return NULL;
230 }
231#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000232 /* Convert lists to fd_sets, and get maximum fd number
233 * propagates the Python exception set in list2set()
234 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000235 rfd2obj[0].sentinel = -1;
236 wfd2obj[0].sentinel = -1;
237 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000238 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000239 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000240 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000241 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000242 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000243 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000244 max = imax;
245 if (omax > max) max = omax;
246 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000247
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000248 Py_BEGIN_ALLOW_THREADS
249 n = select(max, &ifdset, &ofdset, &efdset, tvp);
250 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000251
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000252 if (n < 0) {
253 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000254 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000255 else if (n == 0) {
256 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000257 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000258 if (ifdlist) {
259 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
260 Py_DECREF(ifdlist);
261 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000262 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000263 else {
264 /* any of these three calls can raise an exception. it's more
265 convenient to test for this after all three calls... but
266 is that acceptable?
267 */
268 ifdlist = set2list(&ifdset, rfd2obj);
269 ofdlist = set2list(&ofdset, wfd2obj);
270 efdlist = set2list(&efdset, efd2obj);
271 if (PyErr_Occurred())
272 ret = NULL;
273 else
274 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000275
Barry Warsawc1cb3601996-12-12 22:16:21 +0000276 Py_DECREF(ifdlist);
277 Py_DECREF(ofdlist);
278 Py_DECREF(efdlist);
279 }
280
281 finally:
282 reap_obj(rfd2obj);
283 reap_obj(wfd2obj);
284 reap_obj(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000285#ifdef MS_WINDOWS
286 PyMem_DEL(rfd2obj);
287 PyMem_DEL(wfd2obj);
288 PyMem_DEL(efd2obj);
289#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000290 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000291}
292
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000293#ifdef HAVE_POLL
294/*
295 * poll() support
296 */
297
298typedef struct {
299 PyObject_HEAD
300 PyObject *dict;
301 int ufd_uptodate;
302 int ufd_len;
303 struct pollfd *ufds;
304} pollObject;
305
306staticforward PyTypeObject poll_Type;
307
308/* Update the malloc'ed array of pollfds to match the dictionary
309 contained within a pollObject. Return 1 on success, 0 on an error.
310*/
311
312static int
313update_ufd_array(pollObject *self)
314{
315 int i, j, pos;
316 PyObject *key, *value;
317
318 self->ufd_len = PyDict_Size(self->dict);
319 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
320 if (self->ufds == NULL) {
321 PyErr_NoMemory();
322 return 0;
323 }
324
325 i = pos = 0;
326 while ((j = PyDict_Next(self->dict, &pos, &key, &value))) {
327 self->ufds[i].fd = PyInt_AsLong(key);
328 self->ufds[i].events = PyInt_AsLong(value);
329 i++;
330 }
331 self->ufd_uptodate = 1;
332 return 1;
333}
334
335static char poll_register_doc[] =
336"register(fd [, eventmask] ) -> None\n\n\
337Register a file descriptor with the polling object.\n\
338fd -- either an integer, or an object with a fileno() method returning an int.\n\
339events -- an optional bitmask describing the type of events to check for";
340
341static PyObject *
342poll_register(pollObject *self, PyObject *args)
343{
344 PyObject *o, *key, *value;
345 int fd, events = POLLIN | POLLPRI | POLLOUT;
346
347 if (!PyArg_ParseTuple(args, "O|i", &o, &events)) {
348 return NULL;
349 }
350
351 fd = PyObject_AsFileDescriptor(o);
352 if (fd == -1) return NULL;
353
354 /* Add entry to the internal dictionary: the key is the
355 file descriptor, and the value is the event mask. */
356 if ( (NULL == (key = PyInt_FromLong(fd))) ||
357 (NULL == (value = PyInt_FromLong(events))) ||
358 (PyDict_SetItem(self->dict, key, value)) == -1) {
359 return NULL;
360 }
361 self->ufd_uptodate = 0;
362
363 Py_INCREF(Py_None);
364 return Py_None;
365}
366
367static char poll_unregister_doc[] =
368"unregister(fd) -> None\n\n\
369Remove a file descriptor being tracked by the polling object.";
370
371static PyObject *
372poll_unregister(pollObject *self, PyObject *args)
373{
374 PyObject *o, *key;
375 int fd;
376
377 if (!PyArg_ParseTuple(args, "O", &o)) {
378 return NULL;
379 }
380
381 fd = PyObject_AsFileDescriptor( o );
382 if (fd == -1)
383 return NULL;
384
385 /* Check whether the fd is already in the array */
386 key = PyInt_FromLong(fd);
387 if (key == NULL)
388 return NULL;
389
390 if (PyDict_DelItem(self->dict, key) == -1) {
391 Py_DECREF(key);
392 /* This will simply raise the KeyError set by PyDict_DelItem
393 if the file descriptor isn't registered. */
394 return NULL;
395 }
396
397 Py_DECREF(key);
398 self->ufd_uptodate = 0;
399
400 Py_INCREF(Py_None);
401 return Py_None;
402}
403
404static char poll_poll_doc[] =
405"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
406Polls the set of registered file descriptors, returning a list containing \n\
407any descriptors that have events or errors to report.";
408
409static PyObject *
410poll_poll(pollObject *self, PyObject *args)
411{
412 PyObject *result_list = NULL, *tout = NULL;
413 int timeout = 0, poll_result, i, j;
414 PyObject *value = NULL, *num = NULL;
415
416 if (!PyArg_ParseTuple(args, "|O", &tout)) {
417 return NULL;
418 }
419
420 /* Check values for timeout */
421 if (tout == NULL || tout == Py_None)
422 timeout = -1;
423 else if (!PyArg_Parse(tout, "i", &timeout)) {
424 PyErr_SetString(PyExc_TypeError,
425 "timeout must be an integer or None");
426 return NULL;
427 }
428
429 /* Ensure the ufd array is up to date */
430 if (!self->ufd_uptodate)
431 if (update_ufd_array(self) == 0)
432 return NULL;
433
434 /* call poll() */
435 Py_BEGIN_ALLOW_THREADS;
436 poll_result = poll(self->ufds, self->ufd_len, timeout);
437 Py_END_ALLOW_THREADS;
438
439 if (poll_result < 0) {
440 PyErr_SetFromErrno(SelectError);
441 return NULL;
442 }
443
444 /* build the result list */
445
446 result_list = PyList_New(poll_result);
447 if (!result_list)
448 return NULL;
449 else {
450 for (i = 0, j = 0; j < poll_result; j++) {
451 /* skip to the next fired descriptor */
452 while (!self->ufds[i].revents) {
453 i++;
454 }
455 /* if we hit a NULL return, set value to NULL
456 and break out of loop; code at end will
457 clean up result_list */
458 value = PyTuple_New(2);
459 if (value == NULL)
460 goto error;
461 num = PyInt_FromLong(self->ufds[i].fd);
462 if (num == NULL) {
463 Py_DECREF(value);
464 goto error;
465 }
466 PyTuple_SET_ITEM(value, 0, num);
467
468 num = PyInt_FromLong(self->ufds[i].revents);
469 if (num == NULL) {
470 Py_DECREF(value);
471 goto error;
472 }
473 PyTuple_SET_ITEM(value, 1, num);
474 if ((PyList_SetItem(result_list, j, value)) == -1) {
475 Py_DECREF(value);
476 goto error;
477 }
478 i++;
479 }
480 }
481 return result_list;
482
483 error:
484 Py_DECREF(result_list);
485 return NULL;
486}
487
488static PyMethodDef poll_methods[] = {
489 {"register", (PyCFunction)poll_register,
490 METH_VARARGS, poll_register_doc},
491 {"unregister", (PyCFunction)poll_unregister,
492 METH_VARARGS, poll_unregister_doc},
493 {"poll", (PyCFunction)poll_poll,
494 METH_VARARGS, poll_poll_doc},
495 {NULL, NULL} /* sentinel */
496};
497
498static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000499newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000500{
501 pollObject *self;
502 self = PyObject_New(pollObject, &poll_Type);
503 if (self == NULL)
504 return NULL;
505 /* ufd_uptodate is a Boolean, denoting whether the
506 array pointed to by ufds matches the contents of the dictionary. */
507 self->ufd_uptodate = 0;
508 self->ufds = NULL;
509 self->dict = PyDict_New();
510 if (self->dict == NULL) {
511 Py_DECREF(self);
512 return NULL;
513 }
514 return self;
515}
516
517static void
518poll_dealloc(pollObject *self)
519{
520 if (self->ufds != NULL)
521 PyMem_DEL(self->ufds);
522 Py_XDECREF(self->dict);
523 PyObject_Del(self);
524}
525
526static PyObject *
527poll_getattr(pollObject *self, char *name)
528{
529 return Py_FindMethod(poll_methods, (PyObject *)self, name);
530}
531
532statichere PyTypeObject poll_Type = {
533 /* The ob_type field must be initialized in the module init function
534 * to be portable to Windows without using C++. */
535 PyObject_HEAD_INIT(NULL)
536 0, /*ob_size*/
537 "poll", /*tp_name*/
538 sizeof(pollObject), /*tp_basicsize*/
539 0, /*tp_itemsize*/
540 /* methods */
541 (destructor)poll_dealloc, /*tp_dealloc*/
542 0, /*tp_print*/
543 (getattrfunc)poll_getattr, /*tp_getattr*/
544 0, /*tp_setattr*/
545 0, /*tp_compare*/
546 0, /*tp_repr*/
547 0, /*tp_as_number*/
548 0, /*tp_as_sequence*/
549 0, /*tp_as_mapping*/
550 0, /*tp_hash*/
551};
552
553static char poll_doc[] =
554"Returns a polling object, which supports registering and\n\
555unregistering file descriptors, and then polling them for I/O events.";
556
557static PyObject *
558select_poll(PyObject *self, PyObject *args)
559{
560 pollObject *rv;
561
562 if (!PyArg_ParseTuple(args, ":poll"))
563 return NULL;
564 rv = newPollObject();
565 if ( rv == NULL )
566 return NULL;
567 return (PyObject *)rv;
568}
569#endif /* HAVE_POLL */
570
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000571static char select_doc[] =
572"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
573\n\
574Wait until one or more file descriptors are ready for some kind of I/O.\n\
575The first three arguments are lists of file descriptors to be waited for:\n\
576rlist -- wait until ready for reading\n\
577wlist -- wait until ready for writing\n\
578xlist -- wait for an ``exceptional condition''\n\
579If only one kind of condition is required, pass [] for the other lists.\n\
580A file descriptor is either a socket or file object, or a small integer\n\
581gotten from a fileno() method call on one of those.\n\
582\n\
583The optional 4th argument specifies a timeout in seconds; it may be\n\
584a floating point number to specify fractions of seconds. If it is absent\n\
585or None, the call will never time out.\n\
586\n\
587The return value is a tuple of three lists corresponding to the first three\n\
588arguments; each contains the subset of the corresponding file descriptors\n\
589that are ready.\n\
590\n\
591*** IMPORTANT NOTICE ***\n\
592On Windows, only sockets are supported; on Unix, all file descriptors.";
593
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000594static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000595 {"select", select_select, METH_VARARGS, select_doc},
596#ifdef HAVE_POLL
597 {"poll", select_poll, METH_VARARGS, poll_doc},
598#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000599 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000600};
601
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000602static char module_doc[] =
603"This module supports asynchronous I/O on multiple file descriptors.\n\
604\n\
605*** IMPORTANT NOTICE ***\n\
606On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000607
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000608/*
609 * Convenience routine to export an integer value.
610 * For simplicity, errors (which are unlikely anyway) are ignored.
611 */
612
613static void
614insint(PyObject *d, char *name, int value)
615{
616 PyObject *v = PyInt_FromLong((long) value);
617 if (v == NULL) {
618 /* Don't bother reporting this error */
619 PyErr_Clear();
620 }
621 else {
622 PyDict_SetItemString(d, name, v);
623 Py_DECREF(v);
624 }
625}
626
Guido van Rossum3886bb61998-12-04 18:50:17 +0000627DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000628initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000629{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000630 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000631 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000632 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000633 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000634 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000635#ifdef HAVE_POLL
636 poll_Type.ob_type = &PyType_Type;
637 insint(d, "POLLIN", POLLIN);
638 insint(d, "POLLPRI", POLLPRI);
639 insint(d, "POLLOUT", POLLOUT);
640 insint(d, "POLLERR", POLLERR);
641 insint(d, "POLLHUP", POLLHUP);
642 insint(d, "POLLNVAL", POLLNVAL);
643
644 insint(d, "POLLRDNORM", POLLRDNORM);
645 insint(d, "POLLRDBAND", POLLRDBAND);
646 insint(d, "POLLWRNORM", POLLWRNORM);
647 insint(d, "POLLWRBAND", POLLWRBAND);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000648#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000649 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000650#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000651#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000652}