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