1*34f9b3eeSRoland Mainz /***********************************************************************
2*34f9b3eeSRoland Mainz * *
3*34f9b3eeSRoland Mainz * This software is part of the ast package *
4*34f9b3eeSRoland Mainz * Copyright (c) 1982-2009 AT&T Intellectual Property *
5*34f9b3eeSRoland Mainz * and is licensed under the *
6*34f9b3eeSRoland Mainz * Common Public License, Version 1.0 *
7*34f9b3eeSRoland Mainz * by AT&T Intellectual Property *
8*34f9b3eeSRoland Mainz * *
9*34f9b3eeSRoland Mainz * A copy of the License is available at *
10*34f9b3eeSRoland Mainz * http://www.opensource.org/licenses/cpl1.0.txt *
11*34f9b3eeSRoland Mainz * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12*34f9b3eeSRoland Mainz * *
13*34f9b3eeSRoland Mainz * Information and Software Systems Research *
14*34f9b3eeSRoland Mainz * AT&T Research *
15*34f9b3eeSRoland Mainz * Florham Park NJ *
16*34f9b3eeSRoland Mainz * *
17*34f9b3eeSRoland Mainz * Roland Mainz <roland.mainz@nrubsig.org> *
18*34f9b3eeSRoland Mainz * *
19*34f9b3eeSRoland Mainz ***********************************************************************/
20*34f9b3eeSRoland Mainz #pragma prototyped
21*34f9b3eeSRoland Mainz
22*34f9b3eeSRoland Mainz #include <shell.h>
23*34f9b3eeSRoland Mainz #include <stdio.h>
24*34f9b3eeSRoland Mainz #include <stdbool.h>
25*34f9b3eeSRoland Mainz #include <option.h>
26*34f9b3eeSRoland Mainz #include <stk.h>
27*34f9b3eeSRoland Mainz #include <tm.h>
28*34f9b3eeSRoland Mainz #include "name.h"
29*34f9b3eeSRoland Mainz #undef nv_isnull
30*34f9b3eeSRoland Mainz #ifndef SH_DICT
31*34f9b3eeSRoland Mainz # define SH_DICT "libshell"
32*34f9b3eeSRoland Mainz #endif
33*34f9b3eeSRoland Mainz #include <poll.h>
34*34f9b3eeSRoland Mainz #ifdef __GNUC__
35*34f9b3eeSRoland Mainz #include <alloca.h>
36*34f9b3eeSRoland Mainz #endif /* __GNUC__ */
37*34f9b3eeSRoland Mainz
38*34f9b3eeSRoland Mainz #define sh_contexttoshb(context) ((Shbltin_t*)(context))
39*34f9b3eeSRoland Mainz #define sh_contexttoshell(context) ((context)?(sh_contexttoshb(context)->shp):(NULL))
40*34f9b3eeSRoland Mainz
41*34f9b3eeSRoland Mainz static const char sh_optpoll[] =
42*34f9b3eeSRoland Mainz "[-?\n@(#)$Id: poll (AT&T Labs Research) 2009-05-14 $\n]"
43*34f9b3eeSRoland Mainz "[-author?Roland Mainz <roland.mainz@nrubsig.org]"
44*34f9b3eeSRoland Mainz "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
45*34f9b3eeSRoland Mainz "[+NAME? poll - input/output multiplexing]"
46*34f9b3eeSRoland Mainz "[+DESCRIPTION?The poll command provides applications with a mechanism "
47*34f9b3eeSRoland Mainz "for multiplexing input/output over a set of file descriptors. "
48*34f9b3eeSRoland Mainz "For each member of the array variable \bvar\b, "
49*34f9b3eeSRoland Mainz "poll examines the given file descriptor in the subscript \b.fd\b "
50*34f9b3eeSRoland Mainz "for the event(s) specified in the subscript \b.events\b."
51*34f9b3eeSRoland Mainz "The poll command identifies those file descriptors on which an "
52*34f9b3eeSRoland Mainz "application can read or write data, or on which certain events have "
53*34f9b3eeSRoland Mainz "occurred.]"
54*34f9b3eeSRoland Mainz "[+?The \bvar\b argument specifies the file descriptors to be examined "
55*34f9b3eeSRoland Mainz "and the events of interest for each file descriptor. "
56*34f9b3eeSRoland Mainz "It is a array of structured variables with one member for each open "
57*34f9b3eeSRoland Mainz "file descriptor of interest. The array's members contain the following "
58*34f9b3eeSRoland Mainz "subscripts:]{"
59*34f9b3eeSRoland Mainz "[+?\b.fd\b # file descriptor]"
60*34f9b3eeSRoland Mainz "[+?\b.events\b # requested events]"
61*34f9b3eeSRoland Mainz "[+?\b.revents\b # returned event]"
62*34f9b3eeSRoland Mainz "}"
63*34f9b3eeSRoland Mainz "[+?The \bfd\b variable specifies an open file descriptor and the "
64*34f9b3eeSRoland Mainz "\bevents\b and \brevents\b members are strings constructed from "
65*34f9b3eeSRoland Mainz "a concaternation of the following event flags, seperated by '|':]"
66*34f9b3eeSRoland Mainz "{ "
67*34f9b3eeSRoland Mainz "[+POLLIN?Data other than high priority data may be "
68*34f9b3eeSRoland Mainz "read without blocking. For STREAMS, this "
69*34f9b3eeSRoland Mainz "flag is set in revents even if the message "
70*34f9b3eeSRoland Mainz "is of zero length.]"
71*34f9b3eeSRoland Mainz "[+POLLRDNORM?Normal data (priority band equals 0) may be "
72*34f9b3eeSRoland Mainz "read without blocking. For STREAMS, this "
73*34f9b3eeSRoland Mainz "flag is set in revents even if the message "
74*34f9b3eeSRoland Mainz "is of zero length.]"
75*34f9b3eeSRoland Mainz "[+POLLRDBAND?Data from a non-zero priority band may be "
76*34f9b3eeSRoland Mainz "read without blocking. For STREAMS, this "
77*34f9b3eeSRoland Mainz "flag is set in revents even if the message "
78*34f9b3eeSRoland Mainz "is of zero length.]"
79*34f9b3eeSRoland Mainz "[+POLLPRI?High priority data may be received without "
80*34f9b3eeSRoland Mainz "blocking. For STREAMS, this flag is set in "
81*34f9b3eeSRoland Mainz "revents even if the message is of zero "
82*34f9b3eeSRoland Mainz "length.]"
83*34f9b3eeSRoland Mainz "[+POLLOUT?Normal data (priority band equals 0) may be "
84*34f9b3eeSRoland Mainz "written without blocking.]"
85*34f9b3eeSRoland Mainz "[+POLLWRNORM?The same as POLLOUT.]"
86*34f9b3eeSRoland Mainz "[+POLLWRBAND?Priority data (priority band > 0) may be "
87*34f9b3eeSRoland Mainz "written. This event only examines bands "
88*34f9b3eeSRoland Mainz "that have been written to at least once.]"
89*34f9b3eeSRoland Mainz "[+POLLERR?An error has occurred on the device or "
90*34f9b3eeSRoland Mainz "stream. This flag is only valid in the "
91*34f9b3eeSRoland Mainz "revents bitmask; it is not used in the "
92*34f9b3eeSRoland Mainz "events member.]"
93*34f9b3eeSRoland Mainz "[+POLLHUP?A hangup has occurred on the stream. This "
94*34f9b3eeSRoland Mainz "event and POLLOUT are mutually exclusive; a "
95*34f9b3eeSRoland Mainz "stream can never be writable if a hangup has "
96*34f9b3eeSRoland Mainz "occurred. However, this event and POLLIN, "
97*34f9b3eeSRoland Mainz ", POLLRDBAND, or POLLPRI are not "
98*34f9b3eeSRoland Mainz "mutually exclusive. This flag is only valid "
99*34f9b3eeSRoland Mainz "in the revents bitmask; it is not used in "
100*34f9b3eeSRoland Mainz "the events member.]"
101*34f9b3eeSRoland Mainz "[+POLLNVAL?The specified fd value does not belong to an "
102*34f9b3eeSRoland Mainz "open file. This flag is only valid in the "
103*34f9b3eeSRoland Mainz "revents member; it is not used in the events "
104*34f9b3eeSRoland Mainz "member.]"
105*34f9b3eeSRoland Mainz "}"
106*34f9b3eeSRoland Mainz "]"
107*34f9b3eeSRoland Mainz
108*34f9b3eeSRoland Mainz "[+?If the value fd is less than 0, events is ignored and "
109*34f9b3eeSRoland Mainz "revents is set to 0 in that entry on return from poll.]"
110*34f9b3eeSRoland Mainz
111*34f9b3eeSRoland Mainz "[+?The results of the poll query are stored in the revents "
112*34f9b3eeSRoland Mainz "member in the \bvar\b structure. POLL*-strings are set in the \brevents\b "
113*34f9b3eeSRoland Mainz "variable to indicate which of the requested events are true. "
114*34f9b3eeSRoland Mainz "If none are true, the \brevents\b will be an empty string when "
115*34f9b3eeSRoland Mainz "the poll command returns. The event flags "
116*34f9b3eeSRoland Mainz "POLLHUP, POLLERR, and POLLNVAL are always set in \brevents\b "
117*34f9b3eeSRoland Mainz "if the conditions they indicate are true; this occurs even "
118*34f9b3eeSRoland Mainz "though these flags were not present in events.]"
119*34f9b3eeSRoland Mainz
120*34f9b3eeSRoland Mainz "[+?If none of the defined events have occurred on any selected "
121*34f9b3eeSRoland Mainz "file descriptor, poll waits at least timeout milliseconds "
122*34f9b3eeSRoland Mainz "for an event to occur on any of the selected file descriptors. "
123*34f9b3eeSRoland Mainz "On a computer where millisecond timing accuracy is not "
124*34f9b3eeSRoland Mainz "available, timeout is rounded up to the nearest legal value "
125*34f9b3eeSRoland Mainz "available on that system. If the value timeout is 0, poll "
126*34f9b3eeSRoland Mainz "returns immediately. If the value of timeout is -1, poll "
127*34f9b3eeSRoland Mainz "blocks until a requested event occurs or until the call is "
128*34f9b3eeSRoland Mainz "interrupted.]"
129*34f9b3eeSRoland Mainz
130*34f9b3eeSRoland Mainz "[+?The poll function supports regular files, terminal and "
131*34f9b3eeSRoland Mainz "pseudo-terminal devices, STREAMS-based files, FIFOs and "
132*34f9b3eeSRoland Mainz "pipes. The behavior of poll on elements of fds that refer "
133*34f9b3eeSRoland Mainz "to other types of file is unspecified.]"
134*34f9b3eeSRoland Mainz
135*34f9b3eeSRoland Mainz "[+?The poll function supports sockets.]"
136*34f9b3eeSRoland Mainz
137*34f9b3eeSRoland Mainz "[+?A file descriptor for a socket that is listening for connections "
138*34f9b3eeSRoland Mainz "will indicate that it is ready for reading, once connections "
139*34f9b3eeSRoland Mainz "are available. A file descriptor for a socket that "
140*34f9b3eeSRoland Mainz "is connecting asynchronously will indicate that it is ready "
141*34f9b3eeSRoland Mainz "for writing, once a connection has been established.]"
142*34f9b3eeSRoland Mainz
143*34f9b3eeSRoland Mainz "[+?Regular files always poll TRUE for reading and writing.]"
144*34f9b3eeSRoland Mainz
145*34f9b3eeSRoland Mainz "[e:eventarray]:[fdcount?Upon successful completion, an indexed array "
146*34f9b3eeSRoland Mainz "of strings is returned which contains a list of array subscripts "
147*34f9b3eeSRoland Mainz "in the poll array which received events.]"
148*34f9b3eeSRoland Mainz "[t:timeout]:[seconds?Timeout in seconds. If the value timeout is 0, "
149*34f9b3eeSRoland Mainz "poll returns immediately. If the value of timeout is -1, poll "
150*34f9b3eeSRoland Mainz "blocks until a requested event occurs or until the call is "
151*34f9b3eeSRoland Mainz "interrupted.]"
152*34f9b3eeSRoland Mainz "[T:mtimeout]:[milliseconds?Timeout in milliseconds. If the value timeout is 0, "
153*34f9b3eeSRoland Mainz "poll returns immediately. If the value of timeout is -1, poll "
154*34f9b3eeSRoland Mainz "blocks until a requested event occurs or until the call is "
155*34f9b3eeSRoland Mainz "interrupted.]"
156*34f9b3eeSRoland Mainz "\n"
157*34f9b3eeSRoland Mainz "\nvar\n"
158*34f9b3eeSRoland Mainz "\n"
159*34f9b3eeSRoland Mainz "[+EXIT STATUS?]{"
160*34f9b3eeSRoland Mainz "[+0?Success.]"
161*34f9b3eeSRoland Mainz "[+>0?An error occurred.]"
162*34f9b3eeSRoland Mainz "}"
163*34f9b3eeSRoland Mainz "[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bpoll\b(2)]"
164*34f9b3eeSRoland Mainz ;
165*34f9b3eeSRoland Mainz
166*34f9b3eeSRoland Mainz /*
167*34f9b3eeSRoland Mainz * |mystpcpy| - like |strcpy()| but returns the end of the buffer
168*34f9b3eeSRoland Mainz *
169*34f9b3eeSRoland Mainz * Copy string s2 to s1. s1 must be large enough.
170*34f9b3eeSRoland Mainz * return s1-1 (position of string terminator ('\0') in destnation buffer).
171*34f9b3eeSRoland Mainz */
172*34f9b3eeSRoland Mainz static
mystpcpy(char * s1,const char * s2)173*34f9b3eeSRoland Mainz char *mystpcpy(char *s1, const char *s2)
174*34f9b3eeSRoland Mainz {
175*34f9b3eeSRoland Mainz while (*s1++ = *s2++)
176*34f9b3eeSRoland Mainz ;
177*34f9b3eeSRoland Mainz return (s1-1);
178*34f9b3eeSRoland Mainz }
179*34f9b3eeSRoland Mainz
180*34f9b3eeSRoland Mainz static
nv_open_fmt(Dt_t * dict,int flags,const char * namefmt,...)181*34f9b3eeSRoland Mainz Namval_t *nv_open_fmt(Dt_t *dict, int flags, const char *namefmt, ...)
182*34f9b3eeSRoland Mainz {
183*34f9b3eeSRoland Mainz char varnamebuff[PATH_MAX];
184*34f9b3eeSRoland Mainz va_list ap;
185*34f9b3eeSRoland Mainz
186*34f9b3eeSRoland Mainz va_start(ap, namefmt);
187*34f9b3eeSRoland Mainz vsnprintf(varnamebuff, sizeof(varnamebuff), namefmt, ap);
188*34f9b3eeSRoland Mainz va_end(ap);
189*34f9b3eeSRoland Mainz
190*34f9b3eeSRoland Mainz return nv_open(varnamebuff, dict, flags);
191*34f9b3eeSRoland Mainz }
192*34f9b3eeSRoland Mainz
193*34f9b3eeSRoland Mainz static
poll_strtoevents(const char * str)194*34f9b3eeSRoland Mainz int poll_strtoevents(const char *str)
195*34f9b3eeSRoland Mainz {
196*34f9b3eeSRoland Mainz int events = 0;
197*34f9b3eeSRoland Mainz
198*34f9b3eeSRoland Mainz if (strstr(str, "POLLIN")) events |= POLLIN;
199*34f9b3eeSRoland Mainz if (strstr(str, "POLLRDNORM")) events |= POLLRDNORM;
200*34f9b3eeSRoland Mainz if (strstr(str, "POLLRDBAND")) events |= POLLRDBAND;
201*34f9b3eeSRoland Mainz if (strstr(str, "POLLPRI")) events |= POLLPRI;
202*34f9b3eeSRoland Mainz if (strstr(str, "POLLOUT")) events |= POLLOUT;
203*34f9b3eeSRoland Mainz if (strstr(str, "POLLWRNORM")) events |= POLLWRNORM;
204*34f9b3eeSRoland Mainz if (strstr(str, "POLLWRBAND")) events |= POLLWRBAND;
205*34f9b3eeSRoland Mainz if (strstr(str, "POLLERR")) events |= POLLERR;
206*34f9b3eeSRoland Mainz if (strstr(str, "POLLHUP")) events |= POLLHUP;
207*34f9b3eeSRoland Mainz if (strstr(str, "POLLNVAL")) events |= POLLNVAL;
208*34f9b3eeSRoland Mainz
209*34f9b3eeSRoland Mainz return events;
210*34f9b3eeSRoland Mainz }
211*34f9b3eeSRoland Mainz
212*34f9b3eeSRoland Mainz
213*34f9b3eeSRoland Mainz static
poll_eventstostr(char * s,int events)214*34f9b3eeSRoland Mainz void poll_eventstostr(char *s, int events)
215*34f9b3eeSRoland Mainz {
216*34f9b3eeSRoland Mainz *s='\0';
217*34f9b3eeSRoland Mainz if (!events)
218*34f9b3eeSRoland Mainz return;
219*34f9b3eeSRoland Mainz
220*34f9b3eeSRoland Mainz if (events & POLLIN) s=mystpcpy(s, "POLLIN|");
221*34f9b3eeSRoland Mainz if (events & POLLRDNORM) s=mystpcpy(s, "POLLRDNORM|");
222*34f9b3eeSRoland Mainz if (events & POLLRDBAND) s=mystpcpy(s, "POLLRDBAND|");
223*34f9b3eeSRoland Mainz if (events & POLLPRI) s=mystpcpy(s, "POLLPRI|");
224*34f9b3eeSRoland Mainz if (events & POLLOUT) s=mystpcpy(s, "POLLOUT|");
225*34f9b3eeSRoland Mainz if (events & POLLWRNORM) s=mystpcpy(s, "POLLWRNORM|");
226*34f9b3eeSRoland Mainz if (events & POLLWRBAND) s=mystpcpy(s, "POLLWRBAND|");
227*34f9b3eeSRoland Mainz if (events & POLLERR) s=mystpcpy(s, "POLLERR|");
228*34f9b3eeSRoland Mainz if (events & POLLHUP) s=mystpcpy(s, "POLLHUP|");
229*34f9b3eeSRoland Mainz if (events & POLLNVAL) s=mystpcpy(s, "POLLNVAL|");
230*34f9b3eeSRoland Mainz
231*34f9b3eeSRoland Mainz /* Remove trailling '|' */
232*34f9b3eeSRoland Mainz s--;
233*34f9b3eeSRoland Mainz if(*s=='|')
234*34f9b3eeSRoland Mainz *s='\0';
235*34f9b3eeSRoland Mainz }
236*34f9b3eeSRoland Mainz
237*34f9b3eeSRoland Mainz #undef getconf
238*34f9b3eeSRoland Mainz #define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0)
239*34f9b3eeSRoland Mainz
b_poll(int argc,char * argv[],void * extra)240*34f9b3eeSRoland Mainz extern int b_poll(int argc, char *argv[], void *extra)
241*34f9b3eeSRoland Mainz {
242*34f9b3eeSRoland Mainz Namval_t *np;
243*34f9b3eeSRoland Mainz Shell_t *shp = sh_contexttoshell(extra);
244*34f9b3eeSRoland Mainz char *varname;
245*34f9b3eeSRoland Mainz int n;
246*34f9b3eeSRoland Mainz int fd;
247*34f9b3eeSRoland Mainz nfds_t numpollfd = 0;
248*34f9b3eeSRoland Mainz int i;
249*34f9b3eeSRoland Mainz char *s;
250*34f9b3eeSRoland Mainz double timeout = -1.;
251*34f9b3eeSRoland Mainz char buff[PATH_MAX*2+1]; /* enogth to hold two variable names */
252*34f9b3eeSRoland Mainz char *eventarrayname = NULL;
253*34f9b3eeSRoland Mainz
254*34f9b3eeSRoland Mainz while (n = optget(argv, sh_optpoll)) switch (n)
255*34f9b3eeSRoland Mainz {
256*34f9b3eeSRoland Mainz case 't':
257*34f9b3eeSRoland Mainz case 'T':
258*34f9b3eeSRoland Mainz errno = 0;
259*34f9b3eeSRoland Mainz timeout = strtod(opt_info.arg, (char **)NULL);
260*34f9b3eeSRoland Mainz if (errno != 0)
261*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "%s: invalid timeout", opt_info.arg);
262*34f9b3eeSRoland Mainz
263*34f9b3eeSRoland Mainz /* -t uses seconds, -T milliseconds */
264*34f9b3eeSRoland Mainz if (n == 't')
265*34f9b3eeSRoland Mainz timeout *= 1000.;
266*34f9b3eeSRoland Mainz break;
267*34f9b3eeSRoland Mainz case 'e':
268*34f9b3eeSRoland Mainz eventarrayname = opt_info.arg;
269*34f9b3eeSRoland Mainz break;
270*34f9b3eeSRoland Mainz case ':':
271*34f9b3eeSRoland Mainz errormsg(SH_DICT, 2, "%s", opt_info.arg);
272*34f9b3eeSRoland Mainz break;
273*34f9b3eeSRoland Mainz case '?':
274*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
275*34f9b3eeSRoland Mainz break;
276*34f9b3eeSRoland Mainz }
277*34f9b3eeSRoland Mainz argc -= opt_info.index;
278*34f9b3eeSRoland Mainz argv += opt_info.index;
279*34f9b3eeSRoland Mainz if(argc!=1)
280*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
281*34f9b3eeSRoland Mainz
282*34f9b3eeSRoland Mainz varname = argv[0];
283*34f9b3eeSRoland Mainz
284*34f9b3eeSRoland Mainz Namval_t *array_np, *array_np_sub;
285*34f9b3eeSRoland Mainz const char *subname;
286*34f9b3eeSRoland Mainz
287*34f9b3eeSRoland Mainz array_np = nv_open(varname, shp->var_tree, NV_NOFAIL|NV_NOADD);
288*34f9b3eeSRoland Mainz if (!array_np)
289*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "cannot find array variable %s", varname);
290*34f9b3eeSRoland Mainz if(!nv_isattr(array_np, NV_ARRAY))
291*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "variable %s is not an array", varname);
292*34f9b3eeSRoland Mainz
293*34f9b3eeSRoland Mainz /* Count number of array elememts. We need to do it "manually" to
294*34f9b3eeSRoland Mainz * handle sparse indexed and associative arrays */
295*34f9b3eeSRoland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
296*34f9b3eeSRoland Mainz array_np_sub = array_np;
297*34f9b3eeSRoland Mainz do
298*34f9b3eeSRoland Mainz {
299*34f9b3eeSRoland Mainz if (!(subname=nv_getsub(array_np_sub)))
300*34f9b3eeSRoland Mainz break;
301*34f9b3eeSRoland Mainz numpollfd++;
302*34f9b3eeSRoland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
303*34f9b3eeSRoland Mainz
304*34f9b3eeSRoland Mainz #ifdef __GNUC__
305*34f9b3eeSRoland Mainz /*
306*34f9b3eeSRoland Mainz * Allocate stack space via |alloca()| for gcc builds since ctfconvert
307*34f9b3eeSRoland Mainz * is unable to handle VLAs from gcc. We need this until CR #6379193
308*34f9b3eeSRoland Mainz * is fixed.
309*34f9b3eeSRoland Mainz */
310*34f9b3eeSRoland Mainz struct pollfd *pollfd = alloca(sizeof(struct pollfd)*(numpollfd+1));
311*34f9b3eeSRoland Mainz #else
312*34f9b3eeSRoland Mainz /* We must allocate one more entry with VLA with zero elements do not work with all compilers */
313*34f9b3eeSRoland Mainz struct pollfd pollfd[numpollfd+1];
314*34f9b3eeSRoland Mainz #endif /* __GNUC__ */
315*34f9b3eeSRoland Mainz
316*34f9b3eeSRoland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
317*34f9b3eeSRoland Mainz array_np_sub = array_np;
318*34f9b3eeSRoland Mainz i = 0;
319*34f9b3eeSRoland Mainz do
320*34f9b3eeSRoland Mainz {
321*34f9b3eeSRoland Mainz if (!(subname=nv_getsub(array_np_sub)))
322*34f9b3eeSRoland Mainz break;
323*34f9b3eeSRoland Mainz
324*34f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL|NV_NOADD, "%s[%s].fd", varname, subname);
325*34f9b3eeSRoland Mainz if (!np)
326*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd %s[%s].fd", varname, subname);
327*34f9b3eeSRoland Mainz fd = (int)nv_getnum(np);
328*34f9b3eeSRoland Mainz if (fd < 0 || fd > OPEN_MAX)
329*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "invalid pollfd fd %d", fd);
330*34f9b3eeSRoland Mainz nv_close(np);
331*34f9b3eeSRoland Mainz pollfd[i].fd = fd;
332*34f9b3eeSRoland Mainz
333*34f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL|NV_NOADD, "%s[%s].events", varname, subname);
334*34f9b3eeSRoland Mainz if (!np)
335*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd %s[%s].events", varname, subname);
336*34f9b3eeSRoland Mainz
337*34f9b3eeSRoland Mainz s = nv_getval(np);
338*34f9b3eeSRoland Mainz if (!s)
339*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd events value");
340*34f9b3eeSRoland Mainz pollfd[i].events = poll_strtoevents(s);
341*34f9b3eeSRoland Mainz nv_close(np);
342*34f9b3eeSRoland Mainz
343*34f9b3eeSRoland Mainz pollfd[i].revents = 0;
344*34f9b3eeSRoland Mainz
345*34f9b3eeSRoland Mainz i++;
346*34f9b3eeSRoland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
347*34f9b3eeSRoland Mainz
348*34f9b3eeSRoland Mainz n = poll(pollfd, numpollfd, timeout);
349*34f9b3eeSRoland Mainz /* FixMe: EGAIN and EINTR may require extra handling */
350*34f9b3eeSRoland Mainz if (n < 0)
351*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "failure");
352*34f9b3eeSRoland Mainz
353*34f9b3eeSRoland Mainz if (eventarrayname)
354*34f9b3eeSRoland Mainz {
355*34f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_ARRAY|NV_NOFAIL, "%s", eventarrayname);
356*34f9b3eeSRoland Mainz if (!np)
357*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "couldn't create poll count variable %s", eventarrayname);
358*34f9b3eeSRoland Mainz nv_close(np);
359*34f9b3eeSRoland Mainz }
360*34f9b3eeSRoland Mainz
361*34f9b3eeSRoland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
362*34f9b3eeSRoland Mainz array_np_sub = array_np;
363*34f9b3eeSRoland Mainz i = 0;
364*34f9b3eeSRoland Mainz do
365*34f9b3eeSRoland Mainz {
366*34f9b3eeSRoland Mainz if (!(subname=nv_getsub(array_np_sub)))
367*34f9b3eeSRoland Mainz break;
368*34f9b3eeSRoland Mainz
369*34f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL, "%s[%s].revents", varname, subname);
370*34f9b3eeSRoland Mainz if (!np)
371*34f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "couldn't create pollfd %s[%s].revents", varname, subname);
372*34f9b3eeSRoland Mainz
373*34f9b3eeSRoland Mainz poll_eventstostr(buff, pollfd[i].revents);
374*34f9b3eeSRoland Mainz
375*34f9b3eeSRoland Mainz nv_putval(np, buff, 0);
376*34f9b3eeSRoland Mainz nv_close(np);
377*34f9b3eeSRoland Mainz
378*34f9b3eeSRoland Mainz if (eventarrayname && pollfd[i].revents)
379*34f9b3eeSRoland Mainz {
380*34f9b3eeSRoland Mainz sprintf(buff, "%s+=( '%s' )", eventarrayname, subname);
381*34f9b3eeSRoland Mainz sh_trap(buff, 0);
382*34f9b3eeSRoland Mainz }
383*34f9b3eeSRoland Mainz
384*34f9b3eeSRoland Mainz i++;
385*34f9b3eeSRoland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
386*34f9b3eeSRoland Mainz
387*34f9b3eeSRoland Mainz nv_close(array_np);
388*34f9b3eeSRoland Mainz
389*34f9b3eeSRoland Mainz return(0);
390*34f9b3eeSRoland Mainz }
391