blob: f02b15a8ae490d95c771eb80fe75c082d14457d8 [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
Tim Peters4b046c22001-08-16 21:59:46 +000074reap_obj(pylist fd2obj[FD_SETSIZE + 1])
Barry Warsawc1cb3601996-12-12 22:16:21 +000075{
76 int i;
Tim Peters4b046c22001-08-16 21:59:46 +000077 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
Barry Warsawc1cb3601996-12-12 22:16:21 +000078 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
Tim Peters4b046c22001-08-16 21:59:46 +000089list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
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 *
Tim Peters4b046c22001-08-16 21:59:46 +0000144set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
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 pylist *rfd2obj, *wfd2obj, *efd2obj;
Barry Warsawb44740f2001-08-16 16:52:59 +0000194#else /* !SELECT_USES_HEAP */
Tim Peters4b046c22001-08-16 21:59:46 +0000195 /* XXX: All this should probably be implemented as follows:
Barry Warsawb44740f2001-08-16 16:52:59 +0000196 * - find the highest descriptor we're interested in
197 * - add one
198 * - that's the size
199 * See: Stevens, APitUE, $12.5.1
200 */
Tim Peters4b046c22001-08-16 21:59:46 +0000201 pylist rfd2obj[FD_SETSIZE + 1];
202 pylist wfd2obj[FD_SETSIZE + 1];
203 pylist efd2obj[FD_SETSIZE + 1];
Barry Warsawb44740f2001-08-16 16:52:59 +0000204#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000205 PyObject *ifdlist, *ofdlist, *efdlist;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000206 PyObject *ret = NULL;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000207 PyObject *tout = Py_None;
208 fd_set ifdset, ofdset, efdset;
209 double timeout;
210 struct timeval tv, *tvp;
Guido van Rossum3262e162000-06-28 21:18:13 +0000211 long seconds;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000212 int imax, omax, emax, max;
213 int n;
Guido van Rossumed233a51992-06-23 09:07:03 +0000214
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000215 /* convert arguments */
Guido van Rossum43713e52000-02-29 13:59:29 +0000216 if (!PyArg_ParseTuple(args, "OOO|O:select",
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000217 &ifdlist, &ofdlist, &efdlist, &tout))
218 return NULL;
Guido van Rossumed233a51992-06-23 09:07:03 +0000219
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000220 if (tout == Py_None)
221 tvp = (struct timeval *)0;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000222 else if (!PyArg_Parse(tout, "d", &timeout)) {
223 PyErr_SetString(PyExc_TypeError,
224 "timeout must be a float or None");
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000225 return NULL;
Barry Warsawc1cb3601996-12-12 22:16:21 +0000226 }
Guido van Rossumc7a22701993-11-01 16:27:16 +0000227 else {
Guido van Rossum3262e162000-06-28 21:18:13 +0000228 if (timeout > (double)LONG_MAX) {
Barry Warsaw2f704552001-08-16 16:55:10 +0000229 PyErr_SetString(PyExc_OverflowError,
230 "timeout period too long");
Guido van Rossum3262e162000-06-28 21:18:13 +0000231 return NULL;
232 }
233 seconds = (long)timeout;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000234 timeout = timeout - (double)seconds;
235 tv.tv_sec = seconds;
Guido van Rossum3262e162000-06-28 21:18:13 +0000236 tv.tv_usec = (long)(timeout*1000000.0);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000237 tvp = &tv;
Guido van Rossumc7a22701993-11-01 16:27:16 +0000238 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000239
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000240 /* sanity check first three arguments */
241 if (!PyList_Check(ifdlist) ||
242 !PyList_Check(ofdlist) ||
243 !PyList_Check(efdlist))
244 {
245 PyErr_SetString(PyExc_TypeError,
246 "arguments 1-3 must be lists");
247 return NULL;
248 }
Guido van Rossumed233a51992-06-23 09:07:03 +0000249
Barry Warsawb44740f2001-08-16 16:52:59 +0000250#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000251 /* Allocate memory for the lists */
Tim Peters4b046c22001-08-16 21:59:46 +0000252 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
253 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
254 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000255 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000256 if (rfd2obj) PyMem_DEL(rfd2obj);
257 if (wfd2obj) PyMem_DEL(wfd2obj);
258 if (efd2obj) PyMem_DEL(efd2obj);
Guido van Rossumd20781b1998-07-02 02:53:36 +0000259 return NULL;
260 }
Barry Warsawb44740f2001-08-16 16:52:59 +0000261#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000262 /* Convert lists to fd_sets, and get maximum fd number
263 * propagates the Python exception set in list2set()
264 */
Barry Warsawc1cb3601996-12-12 22:16:21 +0000265 rfd2obj[0].sentinel = -1;
266 wfd2obj[0].sentinel = -1;
267 efd2obj[0].sentinel = -1;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000268 if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000269 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000270 if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000271 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000272 if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0)
Barry Warsawc1cb3601996-12-12 22:16:21 +0000273 goto finally;
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000274 max = imax;
275 if (omax > max) max = omax;
276 if (emax > max) max = emax;
Guido van Rossumed233a51992-06-23 09:07:03 +0000277
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000278 Py_BEGIN_ALLOW_THREADS
279 n = select(max, &ifdset, &ofdset, &efdset, tvp);
280 Py_END_ALLOW_THREADS
Guido van Rossumed233a51992-06-23 09:07:03 +0000281
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000282 if (n < 0) {
283 PyErr_SetFromErrno(SelectError);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000284 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000285 else if (n == 0) {
286 /* optimization */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000287 ifdlist = PyList_New(0);
Barry Warsawc1cb3601996-12-12 22:16:21 +0000288 if (ifdlist) {
289 ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
290 Py_DECREF(ifdlist);
291 }
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000292 }
Barry Warsawc1cb3601996-12-12 22:16:21 +0000293 else {
294 /* any of these three calls can raise an exception. it's more
295 convenient to test for this after all three calls... but
296 is that acceptable?
297 */
298 ifdlist = set2list(&ifdset, rfd2obj);
299 ofdlist = set2list(&ofdset, wfd2obj);
300 efdlist = set2list(&efdset, efd2obj);
301 if (PyErr_Occurred())
302 ret = NULL;
303 else
304 ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000305
Barry Warsawc1cb3601996-12-12 22:16:21 +0000306 Py_DECREF(ifdlist);
307 Py_DECREF(ofdlist);
308 Py_DECREF(efdlist);
309 }
310
311 finally:
312 reap_obj(rfd2obj);
313 reap_obj(wfd2obj);
314 reap_obj(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000315#ifdef SELECT_USES_HEAP
Guido van Rossumd20781b1998-07-02 02:53:36 +0000316 PyMem_DEL(rfd2obj);
317 PyMem_DEL(wfd2obj);
318 PyMem_DEL(efd2obj);
Barry Warsawb44740f2001-08-16 16:52:59 +0000319#endif /* SELECT_USES_HEAP */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000320 return ret;
Guido van Rossumed233a51992-06-23 09:07:03 +0000321}
322
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000323#ifdef HAVE_POLL
324/*
325 * poll() support
326 */
327
328typedef struct {
329 PyObject_HEAD
330 PyObject *dict;
331 int ufd_uptodate;
332 int ufd_len;
333 struct pollfd *ufds;
334} pollObject;
335
336staticforward PyTypeObject poll_Type;
337
338/* Update the malloc'ed array of pollfds to match the dictionary
339 contained within a pollObject. Return 1 on success, 0 on an error.
340*/
341
342static int
343update_ufd_array(pollObject *self)
344{
Fred Drakedff3a372001-07-19 21:29:49 +0000345 int i, pos;
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000346 PyObject *key, *value;
347
348 self->ufd_len = PyDict_Size(self->dict);
349 PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
350 if (self->ufds == NULL) {
351 PyErr_NoMemory();
352 return 0;
353 }
354
355 i = pos = 0;
Fred Drakedff3a372001-07-19 21:29:49 +0000356 while (PyDict_Next(self->dict, &pos, &key, &value)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000357 self->ufds[i].fd = PyInt_AsLong(key);
Fred Drakedff3a372001-07-19 21:29:49 +0000358 self->ufds[i].events = (short)PyInt_AsLong(value);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000359 i++;
360 }
361 self->ufd_uptodate = 1;
362 return 1;
363}
364
365static char poll_register_doc[] =
366"register(fd [, eventmask] ) -> None\n\n\
367Register a file descriptor with the polling object.\n\
Barry Warsaw2f704552001-08-16 16:55:10 +0000368fd -- either an integer, or an object with a fileno() method returning an\n\
369 int.\n\
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000370events -- an optional bitmask describing the type of events to check for";
371
372static PyObject *
373poll_register(pollObject *self, PyObject *args)
374{
375 PyObject *o, *key, *value;
376 int fd, events = POLLIN | POLLPRI | POLLOUT;
377
Fred Drake7b87f852001-05-21 03:29:05 +0000378 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000379 return NULL;
380 }
381
382 fd = PyObject_AsFileDescriptor(o);
383 if (fd == -1) return NULL;
384
385 /* Add entry to the internal dictionary: the key is the
386 file descriptor, and the value is the event mask. */
387 if ( (NULL == (key = PyInt_FromLong(fd))) ||
388 (NULL == (value = PyInt_FromLong(events))) ||
389 (PyDict_SetItem(self->dict, key, value)) == -1) {
390 return NULL;
391 }
392 self->ufd_uptodate = 0;
393
394 Py_INCREF(Py_None);
395 return Py_None;
396}
397
398static char poll_unregister_doc[] =
399"unregister(fd) -> None\n\n\
400Remove a file descriptor being tracked by the polling object.";
401
402static PyObject *
403poll_unregister(pollObject *self, PyObject *args)
404{
405 PyObject *o, *key;
406 int fd;
407
Fred Drake7b87f852001-05-21 03:29:05 +0000408 if (!PyArg_ParseTuple(args, "O:unregister", &o)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000409 return NULL;
410 }
411
412 fd = PyObject_AsFileDescriptor( o );
413 if (fd == -1)
414 return NULL;
415
416 /* Check whether the fd is already in the array */
417 key = PyInt_FromLong(fd);
418 if (key == NULL)
419 return NULL;
420
421 if (PyDict_DelItem(self->dict, key) == -1) {
422 Py_DECREF(key);
423 /* This will simply raise the KeyError set by PyDict_DelItem
424 if the file descriptor isn't registered. */
425 return NULL;
426 }
427
428 Py_DECREF(key);
429 self->ufd_uptodate = 0;
430
431 Py_INCREF(Py_None);
432 return Py_None;
433}
434
435static char poll_poll_doc[] =
436"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
437Polls the set of registered file descriptors, returning a list containing \n\
438any descriptors that have events or errors to report.";
439
440static PyObject *
441poll_poll(pollObject *self, PyObject *args)
442{
443 PyObject *result_list = NULL, *tout = NULL;
444 int timeout = 0, poll_result, i, j;
445 PyObject *value = NULL, *num = NULL;
446
Fred Drake7b87f852001-05-21 03:29:05 +0000447 if (!PyArg_ParseTuple(args, "|O:poll", &tout)) {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000448 return NULL;
449 }
450
451 /* Check values for timeout */
452 if (tout == NULL || tout == Py_None)
453 timeout = -1;
454 else if (!PyArg_Parse(tout, "i", &timeout)) {
455 PyErr_SetString(PyExc_TypeError,
456 "timeout must be an integer or None");
457 return NULL;
458 }
459
460 /* Ensure the ufd array is up to date */
461 if (!self->ufd_uptodate)
462 if (update_ufd_array(self) == 0)
463 return NULL;
464
465 /* call poll() */
466 Py_BEGIN_ALLOW_THREADS;
467 poll_result = poll(self->ufds, self->ufd_len, timeout);
468 Py_END_ALLOW_THREADS;
469
470 if (poll_result < 0) {
471 PyErr_SetFromErrno(SelectError);
472 return NULL;
473 }
474
475 /* build the result list */
476
477 result_list = PyList_New(poll_result);
478 if (!result_list)
479 return NULL;
480 else {
481 for (i = 0, j = 0; j < poll_result; j++) {
482 /* skip to the next fired descriptor */
483 while (!self->ufds[i].revents) {
484 i++;
485 }
486 /* if we hit a NULL return, set value to NULL
487 and break out of loop; code at end will
488 clean up result_list */
489 value = PyTuple_New(2);
490 if (value == NULL)
491 goto error;
492 num = PyInt_FromLong(self->ufds[i].fd);
493 if (num == NULL) {
494 Py_DECREF(value);
495 goto error;
496 }
497 PyTuple_SET_ITEM(value, 0, num);
498
499 num = PyInt_FromLong(self->ufds[i].revents);
500 if (num == NULL) {
501 Py_DECREF(value);
502 goto error;
503 }
504 PyTuple_SET_ITEM(value, 1, num);
505 if ((PyList_SetItem(result_list, j, value)) == -1) {
506 Py_DECREF(value);
507 goto error;
508 }
509 i++;
510 }
511 }
512 return result_list;
513
514 error:
515 Py_DECREF(result_list);
516 return NULL;
517}
518
519static PyMethodDef poll_methods[] = {
520 {"register", (PyCFunction)poll_register,
521 METH_VARARGS, poll_register_doc},
522 {"unregister", (PyCFunction)poll_unregister,
523 METH_VARARGS, poll_unregister_doc},
524 {"poll", (PyCFunction)poll_poll,
525 METH_VARARGS, poll_poll_doc},
526 {NULL, NULL} /* sentinel */
527};
528
529static pollObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000530newPollObject(void)
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000531{
532 pollObject *self;
533 self = PyObject_New(pollObject, &poll_Type);
534 if (self == NULL)
535 return NULL;
536 /* ufd_uptodate is a Boolean, denoting whether the
537 array pointed to by ufds matches the contents of the dictionary. */
538 self->ufd_uptodate = 0;
539 self->ufds = NULL;
540 self->dict = PyDict_New();
541 if (self->dict == NULL) {
542 Py_DECREF(self);
543 return NULL;
544 }
545 return self;
546}
547
548static void
549poll_dealloc(pollObject *self)
550{
551 if (self->ufds != NULL)
552 PyMem_DEL(self->ufds);
553 Py_XDECREF(self->dict);
554 PyObject_Del(self);
555}
556
557static PyObject *
558poll_getattr(pollObject *self, char *name)
559{
560 return Py_FindMethod(poll_methods, (PyObject *)self, name);
561}
562
563statichere PyTypeObject poll_Type = {
564 /* The ob_type field must be initialized in the module init function
565 * to be portable to Windows without using C++. */
566 PyObject_HEAD_INIT(NULL)
567 0, /*ob_size*/
568 "poll", /*tp_name*/
569 sizeof(pollObject), /*tp_basicsize*/
570 0, /*tp_itemsize*/
571 /* methods */
572 (destructor)poll_dealloc, /*tp_dealloc*/
573 0, /*tp_print*/
574 (getattrfunc)poll_getattr, /*tp_getattr*/
575 0, /*tp_setattr*/
576 0, /*tp_compare*/
577 0, /*tp_repr*/
578 0, /*tp_as_number*/
579 0, /*tp_as_sequence*/
580 0, /*tp_as_mapping*/
581 0, /*tp_hash*/
582};
583
584static char poll_doc[] =
585"Returns a polling object, which supports registering and\n\
586unregistering file descriptors, and then polling them for I/O events.";
587
588static PyObject *
589select_poll(PyObject *self, PyObject *args)
590{
591 pollObject *rv;
592
593 if (!PyArg_ParseTuple(args, ":poll"))
594 return NULL;
595 rv = newPollObject();
596 if ( rv == NULL )
597 return NULL;
598 return (PyObject *)rv;
599}
600#endif /* HAVE_POLL */
601
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000602static char select_doc[] =
603"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
604\n\
605Wait until one or more file descriptors are ready for some kind of I/O.\n\
606The first three arguments are lists of file descriptors to be waited for:\n\
607rlist -- wait until ready for reading\n\
608wlist -- wait until ready for writing\n\
609xlist -- wait for an ``exceptional condition''\n\
610If only one kind of condition is required, pass [] for the other lists.\n\
611A file descriptor is either a socket or file object, or a small integer\n\
612gotten from a fileno() method call on one of those.\n\
613\n\
614The optional 4th argument specifies a timeout in seconds; it may be\n\
615a floating point number to specify fractions of seconds. If it is absent\n\
616or None, the call will never time out.\n\
617\n\
618The return value is a tuple of three lists corresponding to the first three\n\
619arguments; each contains the subset of the corresponding file descriptors\n\
620that are ready.\n\
621\n\
622*** IMPORTANT NOTICE ***\n\
623On Windows, only sockets are supported; on Unix, all file descriptors.";
624
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000625static PyMethodDef select_methods[] = {
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000626 {"select", select_select, METH_VARARGS, select_doc},
627#ifdef HAVE_POLL
628 {"poll", select_poll, METH_VARARGS, poll_doc},
629#endif /* HAVE_POLL */
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000630 {0, 0}, /* sentinel */
Guido van Rossumed233a51992-06-23 09:07:03 +0000631};
632
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000633static char module_doc[] =
634"This module supports asynchronous I/O on multiple file descriptors.\n\
635\n\
636*** IMPORTANT NOTICE ***\n\
637On Windows, only sockets are supported; on Unix, all file descriptors.";
Guido van Rossumed233a51992-06-23 09:07:03 +0000638
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000639/*
640 * Convenience routine to export an integer value.
641 * For simplicity, errors (which are unlikely anyway) are ignored.
642 */
643
644static void
645insint(PyObject *d, char *name, int value)
646{
647 PyObject *v = PyInt_FromLong((long) value);
648 if (v == NULL) {
649 /* Don't bother reporting this error */
650 PyErr_Clear();
651 }
652 else {
653 PyDict_SetItemString(d, name, v);
654 Py_DECREF(v);
655 }
656}
657
Guido van Rossum3886bb61998-12-04 18:50:17 +0000658DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000659initselect(void)
Guido van Rossumed233a51992-06-23 09:07:03 +0000660{
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000661 PyObject *m, *d;
Guido van Rossum1d8fb2d1998-06-28 16:54:49 +0000662 m = Py_InitModule3("select", select_methods, module_doc);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000663 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000664 SelectError = PyErr_NewException("select.error", NULL, NULL);
Barry Warsawe4ac0aa1996-12-12 00:04:35 +0000665 PyDict_SetItemString(d, "error", SelectError);
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000666#ifdef HAVE_POLL
667 poll_Type.ob_type = &PyType_Type;
668 insint(d, "POLLIN", POLLIN);
669 insint(d, "POLLPRI", POLLPRI);
670 insint(d, "POLLOUT", POLLOUT);
671 insint(d, "POLLERR", POLLERR);
672 insint(d, "POLLHUP", POLLHUP);
673 insint(d, "POLLNVAL", POLLNVAL);
674
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000675#ifdef POLLRDNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000676 insint(d, "POLLRDNORM", POLLRDNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000677#endif
678#ifdef POLLRDBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000679 insint(d, "POLLRDBAND", POLLRDBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000680#endif
681#ifdef POLLWRNORM
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000682 insint(d, "POLLWRNORM", POLLWRNORM);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000683#endif
684#ifdef POLLWRBAND
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000685 insint(d, "POLLWRBAND", POLLWRBAND);
Andrew M. Kuchling36d97eb2000-09-28 21:33:44 +0000686#endif
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000687#ifdef POLLMSG
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000688 insint(d, "POLLMSG", POLLMSG);
Sjoerd Mullender239f8362000-08-25 13:59:18 +0000689#endif
Andrew M. Kuchlingcf96dc82000-08-25 01:15:33 +0000690#endif /* HAVE_POLL */
Guido van Rossumed233a51992-06-23 09:07:03 +0000691}