blob: 1c1f3d8cdbe8f1009605cf6d8686478dfbd24697 [file] [log] [blame]
Guido van Rossumed233a51992-06-23 09:07:03 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumed233a51992-06-23 09:07:03 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumed233a51992-06-23 09:07:03 +00009******************************************************************/
10
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000011/* select - Module containing unix select(2) call.
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000012 Under Unix, the file descriptors are small integers.
13 Under Win32, select only exists for sockets, and sockets may
14 have any value except INVALID_SOCKET.
Guido van Rossumbcc20741998-08-04 22:53:56 +000015 Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
16 >= 0.
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000017*/
Guido van Rossumed233a51992-06-23 09:07:03 +000018
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000019#include "Python.h"
Guido van Rossumed233a51992-06-23 09:07:03 +000020
Guido van Rossuma376cc51996-12-05 23:43:35 +000021#ifdef HAVE_UNISTD_H
22#include <unistd.h>
23#endif
Jack Jansene4b48632000-07-11 21:35:02 +000024#ifdef HAVE_LIMITS_H
25#include <limits.h>
26#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +000027#ifdef HAVE_POLL_H
28#include <poll.h>
29#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000030
Guido van Rossum37273171996-12-09 18:47:43 +000031#ifdef __sgi
32/* This is missing from unistd.h */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000033extern void bzero(void *, int);
Guido van Rossum37273171996-12-09 18:47:43 +000034#endif
35
Guido van Rossumff7e83d1999-08-27 20:39:37 +000036#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000037#include <sys/types.h>
Guido van Rossumff7e83d1999-08-27 20:39:37 +000038#endif
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000039
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000040#if defined(PYOS_OS2)
41#include <sys/time.h>
42#include <utils.h>
43#endif
44
Guido van Rossum6f489d91996-06-28 20:15:15 +000045#ifdef MS_WINDOWS
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000046#include <winsock.h>
47#else
Guido van Rossumbcc20741998-08-04 22:53:56 +000048#ifdef __BEOS__
49#include <net/socket.h>
50#define SOCKET int
51#else
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000052#define SOCKET int
53#endif
Guido van Rossumbcc20741998-08-04 22:53:56 +000054#endif
Guido van Rossumed233a51992-06-23 09:07:03 +000055
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000056static PyObject *SelectError;
Guido van Rossumed233a51992-06-23 09:07:03 +000057
Barry Warsawc1cb3601996-12-12 22:16:21 +000058/* list of Python objects and their file descriptor */
59typedef struct {
60 PyObject *obj; /* owned reference */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000061 SOCKET fd;
Barry Warsawc1cb3601996-12-12 22:16:21 +000062 int sentinel; /* -1 == sentinel */
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000063} pylist;
64
Barry Warsawc1cb3601996-12-12 22:16:21 +000065static void
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000066reap_obj(pylist fd2obj[FD_SETSIZE + 3])
Barry Warsawc1cb3601996-12-12 22:16:21 +000067{
68 int i;
69 for (i = 0; i < FD_SETSIZE + 3 && fd2obj[i].sentinel >= 0; i++) {
70 Py_XDECREF(fd2obj[i].obj);
71 fd2obj[i].obj = NULL;
72 }
73 fd2obj[0].sentinel = -1;
74}
75
76
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000077/* returns -1 and sets the Python exception if an error occurred, otherwise
78 returns a number >= 0
79*/
Guido van Rossum4f0fbf81996-06-12 04:22:53 +000080static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000081list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +000082{
Barry Warsawc1cb3601996-12-12 22:16:21 +000083 int i;
84 int max = -1;
85 int index = 0;
86 int len = PyList_Size(list);
87 PyObject* o = NULL;
Guido van Rossum07432c01995-03-29 16:47:45 +000088
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000089 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +000090 FD_ZERO(set);
Barry Warsawc1cb3601996-12-12 22:16:21 +000091
92 for (i = 0; i < len; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000093 SOCKET v;
94
95 /* any intervening fileno() calls could decr this refcnt */
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000096 if (!(o = PyList_GetItem(list, i)))
Barry Warsaw529fcfe1996-12-16 18:15:34 +000097 return -1;
Barry Warsaw24c4b3d1996-12-13 23:22:42 +000098
Barry Warsawc1cb3601996-12-12 22:16:21 +000099 Py_INCREF(o);
Andrew M. Kuchling9f28a032000-07-13 23:59:35 +0000100 v = PyObject_AsFileDescriptor( o );
101 if (v == -1) goto finally;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000102
Guido van Rossum947a0fa2000-01-14 16:33:09 +0000103#if defined(_MSC_VER)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000104 max = 0; /* not used for Win32 */
105#else /* !_MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000106 if (v < 0 || v >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000107 PyErr_SetString(PyExc_ValueError,
108 "filedescriptor out of range in select()");
109 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000110 }
111 if (v > max)
112 max = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000113#endif /* _MSC_VER */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000114 FD_SET(v, set);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000115
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000116 /* add object and its file descriptor to the list */
117 if (index >= FD_SETSIZE) {
Barry Warsawc1cb3601996-12-12 22:16:21 +0000118 PyErr_SetString(PyExc_ValueError,
119 "too many file descriptors in select()");
120 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000121 }
122 fd2obj[index].obj = o;
123 fd2obj[index].fd = v;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000124 fd2obj[index].sentinel = 0;
125 fd2obj[++index].sentinel = -1;
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000126 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000127 return max+1;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000128
129 finally:
130 Py_XDECREF(o);
131 return -1;
Guido van Rossumed233a51992-06-23 09:07:03 +0000132}
133
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000134/* returns NULL and sets the Python exception if an error occurred */
135static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000136set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
Guido van Rossumed233a51992-06-23 09:07:03 +0000137{
Barry Warsawc1cb3601996-12-12 22:16:21 +0000138 int i, j, count=0;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000139 PyObject *list, *o;
140 SOCKET fd;
Guido van Rossumed233a51992-06-23 09:07:03 +0000141
Barry Warsawc1cb3601996-12-12 22:16:21 +0000142 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000143 if (FD_ISSET(fd2obj[j].fd, set))
Barry Warsawc1cb3601996-12-12 22:16:21 +0000144 count++;
145 }
146 list = PyList_New(count);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000147 if (!list)
148 return NULL;
149
Barry Warsawc1cb3601996-12-12 22:16:21 +0000150 i = 0;
151 for (j = 0; fd2obj[j].sentinel >= 0; j++) {
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000152 fd = fd2obj[j].fd;
153 if (FD_ISSET(fd, set)) {
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000154#ifndef _MSC_VER
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000155 if (fd > FD_SETSIZE) {
156 PyErr_SetString(PyExc_SystemError,
157 "filedescriptor out of range returned in select()");
Barry Warsawc1cb3601996-12-12 22:16:21 +0000158 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000159 }
Guido van Rossum4f0fbf81996-06-12 04:22:53 +0000160#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000161 o = fd2obj[j].obj;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000162 fd2obj[j].obj = NULL;
163 /* transfer ownership */
164 if (PyList_SetItem(list, i, o) < 0)
165 goto finally;
166
167 i++;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000168 }
169 }
170 return list;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000171 finally:
172 Py_DECREF(list);
173 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000174}
Barry Warsawc1cb3601996-12-12 22:16:21 +0000175
Guido van Rossumed233a51992-06-23 09:07:03 +0000176
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000177static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000178select_select(PyObject *self, PyObject *args)
Guido van Rossumed233a51992-06-23 09:07:03 +0000179{
Guido van Rossumd20781b1998-07-02 02:53:36 +0000180#ifdef MS_WINDOWS
181 /* This would be an awful lot of stack space on Windows! */
182 pylist *rfd2obj, *wfd2obj, *efd2obj;
183#else
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000184 pylist rfd2obj[FD_SETSIZE + 3];
185 pylist wfd2obj[FD_SETSIZE + 3];
186 pylist efd2obj[FD_SETSIZE + 3];
Guido van Rossumd20781b1998-07-02 02:53:36 +0000187#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000188 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000189 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000190 PyObject *tout = Py_None;
191 fd_set ifdset, ofdset, efdset;
192 double timeout;
193 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000194 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000195 int imax, omax, emax, max;
196 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000197
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000198 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000199 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000200 &ifdlist, &ofdlist, &efdlist, &tout))
201 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000202
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000203 if (tout == Py_None)
204 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000205 else if (!PyArg_Parse(tout, "d", &timeout)) {
206 PyErr_SetString(PyExc_TypeError,
207 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000208 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000209 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000210 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000211 if (timeout > (double)LONG_MAX) {
212 PyErr_SetString(PyExc_OverflowError, "timeout period too long");
213 return NULL;
214 }
215 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000216 timeout = timeout - (double)seconds;
217 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000218 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000219 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000220 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000221
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000222 /* sanity check first three arguments */
223 if (!PyList_Check(ifdlist) ||
224 !PyList_Check(ofdlist) ||
225 !PyList_Check(efdlist))
226 {
227 PyErr_SetString(PyExc_TypeError,
228 "arguments 1-3 must be lists");
229 return NULL;
230 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000231
Guido van Rossumd20781b1998-07-02 02:53:36 +0000232#ifdef MS_WINDOWS
233 /* Allocate memory for the lists */
234 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
235 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
236 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
237 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000238 if (rfd2obj) PyMem_DEL(rfd2obj);
239 if (wfd2obj) PyMem_DEL(wfd2obj);
240 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000241 return NULL;
242 }
243#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000244 /* Convert lists to fd_sets, and get maximum fd number
245 * propagates the Python exception set in list2set()
246 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000247 rfd2obj[0].sentinel = -1;
248 wfd2obj[0].sentinel = -1;
249 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000250 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000251 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000252 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000253 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000254 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000255 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000256 max = imax;
257 if (omax > max) max = omax;
258 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000259
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000260 Py_BEGIN_ALLOW_THREADS
261 n = select(max, &ifdset, &ofdset, &efdset, tvp);
262 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000263
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000264 if (n < 0) {
265 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000266 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000267 else if (n == 0) {
268 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000269 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000270 if (ifdlist) {
271 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
272 Py_DECREF(ifdlist);
273 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000275 else {
276 /* any of these three calls can raise an exception. it's more
277 convenient to test for this after all three calls... but
278 is that acceptable?
279 */
280 ifdlist = set2list(&ifdset, rfd2obj);
281 ofdlist = set2list(&ofdset, wfd2obj);
282 efdlist = set2list(&efdset, efd2obj);
283 if (PyErr_Occurred())
284 ret = NULL;
285 else
286 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000287
Barry Warsawc1cb3601996-12-12 22:16:21 +0000288 Py_DECREF(ifdlist);
289 Py_DECREF(ofdlist);
290 Py_DECREF(efdlist);
291 }
292
293 finally:
294 reap_obj(rfd2obj);
295 reap_obj(wfd2obj);
296 reap_obj(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000297#ifdef MS_WINDOWS
298 PyMem_DEL(rfd2obj);
299 PyMem_DEL(wfd2obj);
300 PyMem_DEL(efd2obj);
301#endif
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000302 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000303}
304
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000305#ifdef HAVE_POLL
306/*
307 * poll() support
308 */
309
310typedef struct {
311 PyObject_HEAD
312 PyObject *dict;
313 int ufd_uptodate;
314 int ufd_len;
315 struct pollfd *ufds;
316} pollObject;
317
318staticforward PyTypeObject poll_Type;
319
320/* Update the malloc'ed array of pollfds to match the dictionary
321 contained within a pollObject. Return 1 on success, 0 on an error.
322*/
323
324static int
325update_ufd_array(pollObject *self)
326{
327 int i, j, pos;
328 PyObject *key, *value;
329
330 self->ufd_len = PyDict_Size(self->dict);
331 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
332 if (self->ufds == NULL) {
333 PyErr_NoMemory();
334 return 0;
335 }
336
337 i = pos = 0;
338 while ((j = PyDict_Next(self->dict, &pos, &key, &value))) {
339 self->ufds[i].fd = PyInt_AsLong(key);
340 self->ufds[i].events = PyInt_AsLong(value);
341 i++;
342 }
343 self->ufd_uptodate = 1;
344 return 1;
345}
346
347static char poll_register_doc[] =
348"register(fd [, eventmask] ) -> None\n\n\
349Register a file descriptor with the polling object.\n\
350fd -- either an integer, or an object with a fileno() method returning an int.\n\
351events -- an optional bitmask describing the type of events to check for";
352
353static PyObject *
354poll_register(pollObject *self, PyObject *args)
355{
356 PyObject *o, *key, *value;
357 int fd, events = POLLIN | POLLPRI | POLLOUT;
358
359 if (!PyArg_ParseTuple(args, "O|i", &o, &events)) {
360 return NULL;
361 }
362
363 fd = PyObject_AsFileDescriptor(o);
364 if (fd == -1) return NULL;
365
366 /* Add entry to the internal dictionary: the key is the
367 file descriptor, and the value is the event mask. */
368 if ( (NULL == (key = PyInt_FromLong(fd))) ||
369 (NULL == (value = PyInt_FromLong(events))) ||
370 (PyDict_SetItem(self->dict, key, value)) == -1) {
371 return NULL;
372 }
373 self->ufd_uptodate = 0;
374
375 Py_INCREF(Py_None);
376 return Py_None;
377}
378
379static char poll_unregister_doc[] =
380"unregister(fd) -> None\n\n\
381Remove a file descriptor being tracked by the polling object.";
382
383static PyObject *
384poll_unregister(pollObject *self, PyObject *args)
385{
386 PyObject *o, *key;
387 int fd;
388
389 if (!PyArg_ParseTuple(args, "O", &o)) {
390 return NULL;
391 }
392
393 fd = PyObject_AsFileDescriptor( o );
394 if (fd == -1)
395 return NULL;
396
397 /* Check whether the fd is already in the array */
398 key = PyInt_FromLong(fd);
399 if (key == NULL)
400 return NULL;
401
402 if (PyDict_DelItem(self->dict, key) == -1) {
403 Py_DECREF(key);
404 /* This will simply raise the KeyError set by PyDict_DelItem
405 if the file descriptor isn't registered. */
406 return NULL;
407 }
408
409 Py_DECREF(key);
410 self->ufd_uptodate = 0;
411
412 Py_INCREF(Py_None);
413 return Py_None;
414}
415
416static char poll_poll_doc[] =
417"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
418Polls the set of registered file descriptors, returning a list containing \n\
419any descriptors that have events or errors to report.";
420
421static PyObject *
422poll_poll(pollObject *self, PyObject *args)
423{
424 PyObject *result_list = NULL, *tout = NULL;
425 int timeout = 0, poll_result, i, j;
426 PyObject *value = NULL, *num = NULL;
427
428 if (!PyArg_ParseTuple(args, "|O", &tout)) {
429 return NULL;
430 }
431
432 /* Check values for timeout */
433 if (tout == NULL || tout == Py_None)
434 timeout = -1;
435 else if (!PyArg_Parse(tout, "i", &timeout)) {
436 PyErr_SetString(PyExc_TypeError,
437 "timeout must be an integer or None");
438 return NULL;
439 }
440
441 /* Ensure the ufd array is up to date */
442 if (!self->ufd_uptodate)
443 if (update_ufd_array(self) == 0)
444 return NULL;
445
446 /* call poll() */
447 Py_BEGIN_ALLOW_THREADS;
448 poll_result = poll(self->ufds, self->ufd_len, timeout);
449 Py_END_ALLOW_THREADS;
450
451 if (poll_result < 0) {
452 PyErr_SetFromErrno(SelectError);
453 return NULL;
454 }
455
456 /* build the result list */
457
458 result_list = PyList_New(poll_result);
459 if (!result_list)
460 return NULL;
461 else {
462 for (i = 0, j = 0; j < poll_result; j++) {
463 /* skip to the next fired descriptor */
464 while (!self->ufds[i].revents) {
465 i++;
466 }
467 /* if we hit a NULL return, set value to NULL
468 and break out of loop; code at end will
469 clean up result_list */
470 value = PyTuple_New(2);
471 if (value == NULL)
472 goto error;
473 num = PyInt_FromLong(self->ufds[i].fd);
474 if (num == NULL) {
475 Py_DECREF(value);
476 goto error;
477 }
478 PyTuple_SET_ITEM(value, 0, num);
479
480 num = PyInt_FromLong(self->ufds[i].revents);
481 if (num == NULL) {
482 Py_DECREF(value);
483 goto error;
484 }
485 PyTuple_SET_ITEM(value, 1, num);
486 if ((PyList_SetItem(result_list, j, value)) == -1) {
487 Py_DECREF(value);
488 goto error;
489 }
490 i++;
491 }
492 }
493 return result_list;
494
495 error:
496 Py_DECREF(result_list);
497 return NULL;
498}
499
500static PyMethodDef poll_methods[] = {
501 {"register", (PyCFunction)poll_register,
502 METH_VARARGS, poll_register_doc},
503 {"unregister", (PyCFunction)poll_unregister,
504 METH_VARARGS, poll_unregister_doc},
505 {"poll", (PyCFunction)poll_poll,
506 METH_VARARGS, poll_poll_doc},
507 {NULL, NULL} /* sentinel */
508};
509
510static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000511newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000512{
513 pollObject *self;
514 self = PyObject_New(pollObject, &poll_Type);
515 if (self == NULL)
516 return NULL;
517 /* ufd_uptodate is a Boolean, denoting whether the
518 array pointed to by ufds matches the contents of the dictionary. */
519 self->ufd_uptodate = 0;
520 self->ufds = NULL;
521 self->dict = PyDict_New();
522 if (self->dict == NULL) {
523 Py_DECREF(self);
524 return NULL;
525 }
526 return self;
527}
528
529static void
530poll_dealloc(pollObject *self)
531{
532 if (self->ufds != NULL)
533 PyMem_DEL(self->ufds);
534 Py_XDECREF(self->dict);
535 PyObject_Del(self);
536}
537
538static PyObject *
539poll_getattr(pollObject *self, char *name)
540{
541 return Py_FindMethod(poll_methods, (PyObject *)self, name);
542}
543
544statichere PyTypeObject poll_Type = {
545 /* The ob_type field must be initialized in the module init function
546 * to be portable to Windows without using C++. */
547 PyObject_HEAD_INIT(NULL)
548 0, /*ob_size*/
549 "poll", /*tp_name*/
550 sizeof(pollObject), /*tp_basicsize*/
551 0, /*tp_itemsize*/
552 /* methods */
553 (destructor)poll_dealloc, /*tp_dealloc*/
554 0, /*tp_print*/
555 (getattrfunc)poll_getattr, /*tp_getattr*/
556 0, /*tp_setattr*/
557 0, /*tp_compare*/
558 0, /*tp_repr*/
559 0, /*tp_as_number*/
560 0, /*tp_as_sequence*/
561 0, /*tp_as_mapping*/
562 0, /*tp_hash*/
563};
564
565static char poll_doc[] =
566"Returns a polling object, which supports registering and\n\
567unregistering file descriptors, and then polling them for I/O events.";
568
569static PyObject *
570select_poll(PyObject *self, PyObject *args)
571{
572 pollObject *rv;
573
574 if (!PyArg_ParseTuple(args, ":poll"))
575 return NULL;
576 rv = newPollObject();
577 if ( rv == NULL )
578 return NULL;
579 return (PyObject *)rv;
580}
581#endif /* HAVE_POLL */
582
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000583static char select_doc[] =
584"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
585\n\
586Wait until one or more file descriptors are ready for some kind of I/O.\n\
587The first three arguments are lists of file descriptors to be waited for:\n\
588rlist -- wait until ready for reading\n\
589wlist -- wait until ready for writing\n\
590xlist -- wait for an ``exceptional condition''\n\
591If only one kind of condition is required, pass [] for the other lists.\n\
592A file descriptor is either a socket or file object, or a small integer\n\
593gotten from a fileno() method call on one of those.\n\
594\n\
595The optional 4th argument specifies a timeout in seconds; it may be\n\
596a floating point number to specify fractions of seconds. If it is absent\n\
597or None, the call will never time out.\n\
598\n\
599The return value is a tuple of three lists corresponding to the first three\n\
600arguments; each contains the subset of the corresponding file descriptors\n\
601that are ready.\n\
602\n\
603*** IMPORTANT NOTICE ***\n\
604On Windows, only sockets are supported; on Unix, all file descriptors.";
605
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000606static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000607 {"select", select_select, METH_VARARGS, select_doc},
608#ifdef HAVE_POLL
609 {"poll", select_poll, METH_VARARGS, poll_doc},
610#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000611 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000612};
613
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000614static char module_doc[] =
615"This module supports asynchronous I/O on multiple file descriptors.\n\
616\n\
617*** IMPORTANT NOTICE ***\n\
618On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000619
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000620/*
621 * Convenience routine to export an integer value.
622 * For simplicity, errors (which are unlikely anyway) are ignored.
623 */
624
625static void
626insint(PyObject *d, char *name, int value)
627{
628 PyObject *v = PyInt_FromLong((long) value);
629 if (v == NULL) {
630 /* Don't bother reporting this error */
631 PyErr_Clear();
632 }
633 else {
634 PyDict_SetItemString(d, name, v);
635 Py_DECREF(v);
636 }
637}
638
Guido van Rossum3886bb61998-12-04 18:50:17 +0000639DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000640initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000641{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000642 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000643 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000644 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000645 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000646 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000647#ifdef HAVE_POLL
648 poll_Type.ob_type = &PyType_Type;
649 insint(d, "POLLIN", POLLIN);
650 insint(d, "POLLPRI", POLLPRI);
651 insint(d, "POLLOUT", POLLOUT);
652 insint(d, "POLLERR", POLLERR);
653 insint(d, "POLLHUP", POLLHUP);
654 insint(d, "POLLNVAL", POLLNVAL);
655
656 insint(d, "POLLRDNORM", POLLRDNORM);
657 insint(d, "POLLRDBAND", POLLRDBAND);
658 insint(d, "POLLWRNORM", POLLWRNORM);
659 insint(d, "POLLWRBAND", POLLWRBAND);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000660#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000661 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000662#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000663#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000664}