(py-indent-right, py-outdent-left): new commands, bound to C-c C-r and
[python/dscho.git] / Modules / selectmodule.c
bloba9f55c30a5beb648a977cb2f8b9d1bc5565be334
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* select - Module containing unix select(2) call */
27 #include "allobjects.h"
28 #include "modsupport.h"
29 #include "ceval.h"
31 #include <sys/types.h>
32 #include "myselect.h" /* Also includes mytime.h */
34 static object *SelectError;
36 static
37 list2set(list, set, fd2obj)
38 object *list;
39 fd_set *set;
40 object *fd2obj[FD_SETSIZE];
42 int i, len, v, max = -1;
43 object *o, *filenomethod, *fno;
45 FD_ZERO(set);
46 len = getlistsize(list);
47 for( i=0; i<len; i++ ) {
48 o = getlistitem(list, i);
49 if ( is_intobject(o) ) {
50 v = getintvalue(o);
51 } else if ( (filenomethod = getattr(o, "fileno")) != NULL ) {
52 fno = call_object(filenomethod, NULL);
53 DECREF(filenomethod);
54 if ( fno == NULL )
55 return -1;
56 if ( !is_intobject(fno) ) {
57 err_badarg();
58 DECREF(fno);
59 return -1;
61 v = getintvalue(fno);
62 DECREF(fno);
63 } else {
64 err_badarg();
65 return -1;
67 if ( v < 0 || v >= FD_SETSIZE ) {
68 err_setstr(ValueError, "filedescriptor out of range in select()");
69 return -1;
71 if ( v > max ) max = v;
72 FD_SET(v, set);
73 XDECREF(fd2obj[v]);
74 fd2obj[v] = o;
76 return max+1;
79 static object *
80 set2list(set, max, fd2obj)
81 fd_set *set;
82 int max;
83 object *fd2obj[FD_SETSIZE];
85 int i, num=0;
86 object *list, *o;
88 for(i=0; i<max; i++)
89 if ( FD_ISSET(i,set) )
90 num++;
91 list = newlistobject(num);
92 num = 0;
93 for(i=0; i<max; i++)
94 if ( FD_ISSET(i,set) ) {
95 if ( i > FD_SETSIZE ) {
96 err_setstr(SystemError,
97 "filedescriptor out of range returned in select()");
98 return NULL;
100 o = fd2obj[i];
101 if ( o == NULL ) {
102 err_setstr(SystemError,
103 "Bad filedescriptor returned from select()");
104 return NULL;
106 INCREF(o);
107 setlistitem(list, num, o);
108 num++;
110 return list;
113 static object *
114 select_select(self, args)
115 object *self;
116 object *args;
118 object *fd2obj[FD_SETSIZE];
119 object *ifdlist, *ofdlist, *efdlist;
120 object *ret, *tout;
121 fd_set ifdset, ofdset, efdset;
122 double timeout;
123 struct timeval tv, *tvp;
124 int seconds;
125 int imax, omax, emax, max;
126 int n;
129 /* Get args. Looks funny because of optional timeout argument */
130 if ( getargs(args, "(OOOO)", &ifdlist, &ofdlist, &efdlist, &tout) ) {
131 if (tout == None)
132 tvp = (struct timeval *)0;
133 else {
134 if (!getargs(tout, "d;timeout must be float or None", &timeout))
135 return NULL;
136 seconds = (int)timeout;
137 timeout = timeout - (double)seconds;
138 tv.tv_sec = seconds;
139 tv.tv_usec = (int)(timeout*1000000.0);
140 tvp = &tv;
142 } else {
143 /* Doesn't have 4 args, that means no timeout */
144 err_clear();
145 if (!getargs(args, "(OOO)", &ifdlist, &ofdlist, &efdlist) )
146 return 0;
147 tvp = (struct timeval *)0;
149 if ( !is_listobject(ifdlist) || !is_listobject(ofdlist) ||
150 !is_listobject(efdlist) ) {
151 err_badarg();
152 return 0;
155 memset((char *)fd2obj, '\0', sizeof(fd2obj));
157 /* Convert lists to fd_sets, and get maximum fd number */
158 if( (imax=list2set(ifdlist, &ifdset, fd2obj)) < 0 )
159 return 0;
160 if( (omax=list2set(ofdlist, &ofdset, fd2obj)) < 0 )
161 return 0;
162 if( (emax=list2set(efdlist, &efdset, fd2obj)) < 0 )
163 return 0;
164 max = imax;
165 if ( omax > max ) max = omax;
166 if ( emax > max ) max = emax;
168 BGN_SAVE
169 n = select(max, &ifdset, &ofdset, &efdset, tvp);
170 END_SAVE
172 if ( n < 0 ) {
173 err_errno(SelectError);
174 return 0;
177 if ( n == 0 )
178 imax = omax = emax = 0; /* Speedup hack */
180 ifdlist = set2list(&ifdset, imax, fd2obj);
181 ofdlist = set2list(&ofdset, omax, fd2obj);
182 efdlist = set2list(&efdset, emax, fd2obj);
183 ret = mkvalue("OOO", ifdlist, ofdlist, efdlist);
184 XDECREF(ifdlist);
185 XDECREF(ofdlist);
186 XDECREF(efdlist);
187 return ret;
191 static struct methodlist select_methods[] = {
192 { "select", select_select },
193 { 0, 0 },
197 void
198 initselect()
200 object *m, *d;
201 m = initmodule("select", select_methods);
202 d = getmoduledict(m);
203 SelectError = newstringobject("select.error");
204 if ( SelectError == NULL || dictinsert(d, "error", SelectError) )
205 fatal("Cannot define select.error");