134f9b3eeSRoland Mainz /***********************************************************************
234f9b3eeSRoland Mainz * *
334f9b3eeSRoland Mainz * This software is part of the ast package *
434f9b3eeSRoland Mainz * Copyright (c) 1982-2009 AT&T Intellectual Property *
534f9b3eeSRoland Mainz * and is licensed under the *
634f9b3eeSRoland Mainz * Common Public License, Version 1.0 *
734f9b3eeSRoland Mainz * by AT&T Intellectual Property *
834f9b3eeSRoland Mainz * *
934f9b3eeSRoland Mainz * A copy of the License is available at *
1034f9b3eeSRoland Mainz * http://www.opensource.org/licenses/cpl1.0.txt *
1134f9b3eeSRoland Mainz * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1234f9b3eeSRoland Mainz * *
1334f9b3eeSRoland Mainz * Information and Software Systems Research *
1434f9b3eeSRoland Mainz * AT&T Research *
1534f9b3eeSRoland Mainz * Florham Park NJ *
1634f9b3eeSRoland Mainz * *
1734f9b3eeSRoland Mainz * Roland Mainz <roland.mainz@nrubsig.org> *
1834f9b3eeSRoland Mainz * *
1934f9b3eeSRoland Mainz ***********************************************************************/
2034f9b3eeSRoland Mainz #pragma prototyped
2134f9b3eeSRoland Mainz
2234f9b3eeSRoland Mainz #include <shell.h>
2334f9b3eeSRoland Mainz #include <stdio.h>
2434f9b3eeSRoland Mainz #include <stdbool.h>
2534f9b3eeSRoland Mainz #include <option.h>
2634f9b3eeSRoland Mainz #include <stk.h>
2734f9b3eeSRoland Mainz #include <tm.h>
2834f9b3eeSRoland Mainz #include "name.h"
2934f9b3eeSRoland Mainz #undef nv_isnull
3034f9b3eeSRoland Mainz #ifndef SH_DICT
3134f9b3eeSRoland Mainz # define SH_DICT "libshell"
3234f9b3eeSRoland Mainz #endif
3334f9b3eeSRoland Mainz #include <poll.h>
3434f9b3eeSRoland Mainz #ifdef __GNUC__
3534f9b3eeSRoland Mainz #include <alloca.h>
3634f9b3eeSRoland Mainz #endif /* __GNUC__ */
3734f9b3eeSRoland Mainz
3834f9b3eeSRoland Mainz #define sh_contexttoshb(context) ((Shbltin_t*)(context))
3934f9b3eeSRoland Mainz #define sh_contexttoshell(context) ((context)?(sh_contexttoshb(context)->shp):(NULL))
4034f9b3eeSRoland Mainz
4134f9b3eeSRoland Mainz static const char sh_optpoll[] =
4234f9b3eeSRoland Mainz "[-?\n@(#)$Id: poll (AT&T Labs Research) 2009-05-14 $\n]"
4334f9b3eeSRoland Mainz "[-author?Roland Mainz <roland.mainz@nrubsig.org]"
4434f9b3eeSRoland Mainz "[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
4534f9b3eeSRoland Mainz "[+NAME? poll - input/output multiplexing]"
4634f9b3eeSRoland Mainz "[+DESCRIPTION?The poll command provides applications with a mechanism "
4734f9b3eeSRoland Mainz "for multiplexing input/output over a set of file descriptors. "
4834f9b3eeSRoland Mainz "For each member of the array variable \bvar\b, "
4934f9b3eeSRoland Mainz "poll examines the given file descriptor in the subscript \b.fd\b "
5034f9b3eeSRoland Mainz "for the event(s) specified in the subscript \b.events\b."
5134f9b3eeSRoland Mainz "The poll command identifies those file descriptors on which an "
5234f9b3eeSRoland Mainz "application can read or write data, or on which certain events have "
5334f9b3eeSRoland Mainz "occurred.]"
5434f9b3eeSRoland Mainz "[+?The \bvar\b argument specifies the file descriptors to be examined "
5534f9b3eeSRoland Mainz "and the events of interest for each file descriptor. "
5634f9b3eeSRoland Mainz "It is a array of structured variables with one member for each open "
5734f9b3eeSRoland Mainz "file descriptor of interest. The array's members contain the following "
5834f9b3eeSRoland Mainz "subscripts:]{"
5934f9b3eeSRoland Mainz "[+?\b.fd\b # file descriptor]"
6034f9b3eeSRoland Mainz "[+?\b.events\b # requested events]"
6134f9b3eeSRoland Mainz "[+?\b.revents\b # returned event]"
6234f9b3eeSRoland Mainz "}"
6334f9b3eeSRoland Mainz "[+?The \bfd\b variable specifies an open file descriptor and the "
6434f9b3eeSRoland Mainz "\bevents\b and \brevents\b members are strings constructed from "
6534f9b3eeSRoland Mainz "a concaternation of the following event flags, seperated by '|':]"
6634f9b3eeSRoland Mainz "{ "
6734f9b3eeSRoland Mainz "[+POLLIN?Data other than high priority data may be "
6834f9b3eeSRoland Mainz "read without blocking. For STREAMS, this "
6934f9b3eeSRoland Mainz "flag is set in revents even if the message "
7034f9b3eeSRoland Mainz "is of zero length.]"
7134f9b3eeSRoland Mainz "[+POLLRDNORM?Normal data (priority band equals 0) may be "
7234f9b3eeSRoland Mainz "read without blocking. For STREAMS, this "
7334f9b3eeSRoland Mainz "flag is set in revents even if the message "
7434f9b3eeSRoland Mainz "is of zero length.]"
7534f9b3eeSRoland Mainz "[+POLLRDBAND?Data from a non-zero priority band may be "
7634f9b3eeSRoland Mainz "read without blocking. For STREAMS, this "
7734f9b3eeSRoland Mainz "flag is set in revents even if the message "
7834f9b3eeSRoland Mainz "is of zero length.]"
7934f9b3eeSRoland Mainz "[+POLLPRI?High priority data may be received without "
8034f9b3eeSRoland Mainz "blocking. For STREAMS, this flag is set in "
8134f9b3eeSRoland Mainz "revents even if the message is of zero "
8234f9b3eeSRoland Mainz "length.]"
8334f9b3eeSRoland Mainz "[+POLLOUT?Normal data (priority band equals 0) may be "
8434f9b3eeSRoland Mainz "written without blocking.]"
8534f9b3eeSRoland Mainz "[+POLLWRNORM?The same as POLLOUT.]"
8634f9b3eeSRoland Mainz "[+POLLWRBAND?Priority data (priority band > 0) may be "
8734f9b3eeSRoland Mainz "written. This event only examines bands "
8834f9b3eeSRoland Mainz "that have been written to at least once.]"
8934f9b3eeSRoland Mainz "[+POLLERR?An error has occurred on the device or "
9034f9b3eeSRoland Mainz "stream. This flag is only valid in the "
9134f9b3eeSRoland Mainz "revents bitmask; it is not used in the "
9234f9b3eeSRoland Mainz "events member.]"
9334f9b3eeSRoland Mainz "[+POLLHUP?A hangup has occurred on the stream. This "
9434f9b3eeSRoland Mainz "event and POLLOUT are mutually exclusive; a "
9534f9b3eeSRoland Mainz "stream can never be writable if a hangup has "
9634f9b3eeSRoland Mainz "occurred. However, this event and POLLIN, "
9734f9b3eeSRoland Mainz ", POLLRDBAND, or POLLPRI are not "
9834f9b3eeSRoland Mainz "mutually exclusive. This flag is only valid "
9934f9b3eeSRoland Mainz "in the revents bitmask; it is not used in "
10034f9b3eeSRoland Mainz "the events member.]"
10134f9b3eeSRoland Mainz "[+POLLNVAL?The specified fd value does not belong to an "
10234f9b3eeSRoland Mainz "open file. This flag is only valid in the "
10334f9b3eeSRoland Mainz "revents member; it is not used in the events "
10434f9b3eeSRoland Mainz "member.]"
10534f9b3eeSRoland Mainz "}"
10634f9b3eeSRoland Mainz "]"
10734f9b3eeSRoland Mainz
10834f9b3eeSRoland Mainz "[+?If the value fd is less than 0, events is ignored and "
10934f9b3eeSRoland Mainz "revents is set to 0 in that entry on return from poll.]"
11034f9b3eeSRoland Mainz
11134f9b3eeSRoland Mainz "[+?The results of the poll query are stored in the revents "
11234f9b3eeSRoland Mainz "member in the \bvar\b structure. POLL*-strings are set in the \brevents\b "
11334f9b3eeSRoland Mainz "variable to indicate which of the requested events are true. "
11434f9b3eeSRoland Mainz "If none are true, the \brevents\b will be an empty string when "
11534f9b3eeSRoland Mainz "the poll command returns. The event flags "
11634f9b3eeSRoland Mainz "POLLHUP, POLLERR, and POLLNVAL are always set in \brevents\b "
11734f9b3eeSRoland Mainz "if the conditions they indicate are true; this occurs even "
11834f9b3eeSRoland Mainz "though these flags were not present in events.]"
11934f9b3eeSRoland Mainz
12034f9b3eeSRoland Mainz "[+?If none of the defined events have occurred on any selected "
12134f9b3eeSRoland Mainz "file descriptor, poll waits at least timeout milliseconds "
12234f9b3eeSRoland Mainz "for an event to occur on any of the selected file descriptors. "
12334f9b3eeSRoland Mainz "On a computer where millisecond timing accuracy is not "
12434f9b3eeSRoland Mainz "available, timeout is rounded up to the nearest legal value "
12534f9b3eeSRoland Mainz "available on that system. If the value timeout is 0, poll "
12634f9b3eeSRoland Mainz "returns immediately. If the value of timeout is -1, poll "
12734f9b3eeSRoland Mainz "blocks until a requested event occurs or until the call is "
12834f9b3eeSRoland Mainz "interrupted.]"
12934f9b3eeSRoland Mainz
13034f9b3eeSRoland Mainz "[+?The poll function supports regular files, terminal and "
13134f9b3eeSRoland Mainz "pseudo-terminal devices, STREAMS-based files, FIFOs and "
13234f9b3eeSRoland Mainz "pipes. The behavior of poll on elements of fds that refer "
13334f9b3eeSRoland Mainz "to other types of file is unspecified.]"
13434f9b3eeSRoland Mainz
13534f9b3eeSRoland Mainz "[+?The poll function supports sockets.]"
13634f9b3eeSRoland Mainz
13734f9b3eeSRoland Mainz "[+?A file descriptor for a socket that is listening for connections "
13834f9b3eeSRoland Mainz "will indicate that it is ready for reading, once connections "
13934f9b3eeSRoland Mainz "are available. A file descriptor for a socket that "
14034f9b3eeSRoland Mainz "is connecting asynchronously will indicate that it is ready "
14134f9b3eeSRoland Mainz "for writing, once a connection has been established.]"
142*b30d1939SAndy Fiddaman
14334f9b3eeSRoland Mainz "[+?Regular files always poll TRUE for reading and writing.]"
14434f9b3eeSRoland Mainz
14534f9b3eeSRoland Mainz "[e:eventarray]:[fdcount?Upon successful completion, an indexed array "
14634f9b3eeSRoland Mainz "of strings is returned which contains a list of array subscripts "
14734f9b3eeSRoland Mainz "in the poll array which received events.]"
14834f9b3eeSRoland Mainz "[t:timeout]:[seconds?Timeout in seconds. If the value timeout is 0, "
14934f9b3eeSRoland Mainz "poll returns immediately. If the value of timeout is -1, poll "
15034f9b3eeSRoland Mainz "blocks until a requested event occurs or until the call is "
15134f9b3eeSRoland Mainz "interrupted.]"
15234f9b3eeSRoland Mainz "[T:mtimeout]:[milliseconds?Timeout in milliseconds. If the value timeout is 0, "
15334f9b3eeSRoland Mainz "poll returns immediately. If the value of timeout is -1, poll "
15434f9b3eeSRoland Mainz "blocks until a requested event occurs or until the call is "
15534f9b3eeSRoland Mainz "interrupted.]"
15634f9b3eeSRoland Mainz "\n"
15734f9b3eeSRoland Mainz "\nvar\n"
15834f9b3eeSRoland Mainz "\n"
15934f9b3eeSRoland Mainz "[+EXIT STATUS?]{"
16034f9b3eeSRoland Mainz "[+0?Success.]"
16134f9b3eeSRoland Mainz "[+>0?An error occurred.]"
16234f9b3eeSRoland Mainz "}"
16334f9b3eeSRoland Mainz "[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bpoll\b(2)]"
16434f9b3eeSRoland Mainz ;
16534f9b3eeSRoland Mainz
16634f9b3eeSRoland Mainz /*
16734f9b3eeSRoland Mainz * |mystpcpy| - like |strcpy()| but returns the end of the buffer
16834f9b3eeSRoland Mainz *
16934f9b3eeSRoland Mainz * Copy string s2 to s1. s1 must be large enough.
17034f9b3eeSRoland Mainz * return s1-1 (position of string terminator ('\0') in destnation buffer).
17134f9b3eeSRoland Mainz */
17234f9b3eeSRoland Mainz static
mystpcpy(char * s1,const char * s2)17334f9b3eeSRoland Mainz char *mystpcpy(char *s1, const char *s2)
17434f9b3eeSRoland Mainz {
17534f9b3eeSRoland Mainz while (*s1++ = *s2++)
17634f9b3eeSRoland Mainz ;
17734f9b3eeSRoland Mainz return (s1-1);
17834f9b3eeSRoland Mainz }
17934f9b3eeSRoland Mainz
18034f9b3eeSRoland Mainz static
nv_open_fmt(Dt_t * dict,int flags,const char * namefmt,...)18134f9b3eeSRoland Mainz Namval_t *nv_open_fmt(Dt_t *dict, int flags, const char *namefmt, ...)
18234f9b3eeSRoland Mainz {
18334f9b3eeSRoland Mainz char varnamebuff[PATH_MAX];
18434f9b3eeSRoland Mainz va_list ap;
18534f9b3eeSRoland Mainz
18634f9b3eeSRoland Mainz va_start(ap, namefmt);
18734f9b3eeSRoland Mainz vsnprintf(varnamebuff, sizeof(varnamebuff), namefmt, ap);
18834f9b3eeSRoland Mainz va_end(ap);
189*b30d1939SAndy Fiddaman
19034f9b3eeSRoland Mainz return nv_open(varnamebuff, dict, flags);
19134f9b3eeSRoland Mainz }
19234f9b3eeSRoland Mainz
19334f9b3eeSRoland Mainz static
poll_strtoevents(const char * str)19434f9b3eeSRoland Mainz int poll_strtoevents(const char *str)
19534f9b3eeSRoland Mainz {
19634f9b3eeSRoland Mainz int events = 0;
197*b30d1939SAndy Fiddaman
19834f9b3eeSRoland Mainz if (strstr(str, "POLLIN")) events |= POLLIN;
19934f9b3eeSRoland Mainz if (strstr(str, "POLLRDNORM")) events |= POLLRDNORM;
20034f9b3eeSRoland Mainz if (strstr(str, "POLLRDBAND")) events |= POLLRDBAND;
20134f9b3eeSRoland Mainz if (strstr(str, "POLLPRI")) events |= POLLPRI;
20234f9b3eeSRoland Mainz if (strstr(str, "POLLOUT")) events |= POLLOUT;
20334f9b3eeSRoland Mainz if (strstr(str, "POLLWRNORM")) events |= POLLWRNORM;
20434f9b3eeSRoland Mainz if (strstr(str, "POLLWRBAND")) events |= POLLWRBAND;
20534f9b3eeSRoland Mainz if (strstr(str, "POLLERR")) events |= POLLERR;
20634f9b3eeSRoland Mainz if (strstr(str, "POLLHUP")) events |= POLLHUP;
20734f9b3eeSRoland Mainz if (strstr(str, "POLLNVAL")) events |= POLLNVAL;
20834f9b3eeSRoland Mainz
20934f9b3eeSRoland Mainz return events;
21034f9b3eeSRoland Mainz }
21134f9b3eeSRoland Mainz
21234f9b3eeSRoland Mainz
21334f9b3eeSRoland Mainz static
poll_eventstostr(char * s,int events)21434f9b3eeSRoland Mainz void poll_eventstostr(char *s, int events)
21534f9b3eeSRoland Mainz {
21634f9b3eeSRoland Mainz *s='\0';
21734f9b3eeSRoland Mainz if (!events)
21834f9b3eeSRoland Mainz return;
219*b30d1939SAndy Fiddaman
22034f9b3eeSRoland Mainz if (events & POLLIN) s=mystpcpy(s, "POLLIN|");
22134f9b3eeSRoland Mainz if (events & POLLRDNORM) s=mystpcpy(s, "POLLRDNORM|");
22234f9b3eeSRoland Mainz if (events & POLLRDBAND) s=mystpcpy(s, "POLLRDBAND|");
22334f9b3eeSRoland Mainz if (events & POLLPRI) s=mystpcpy(s, "POLLPRI|");
22434f9b3eeSRoland Mainz if (events & POLLOUT) s=mystpcpy(s, "POLLOUT|");
22534f9b3eeSRoland Mainz if (events & POLLWRNORM) s=mystpcpy(s, "POLLWRNORM|");
22634f9b3eeSRoland Mainz if (events & POLLWRBAND) s=mystpcpy(s, "POLLWRBAND|");
22734f9b3eeSRoland Mainz if (events & POLLERR) s=mystpcpy(s, "POLLERR|");
22834f9b3eeSRoland Mainz if (events & POLLHUP) s=mystpcpy(s, "POLLHUP|");
22934f9b3eeSRoland Mainz if (events & POLLNVAL) s=mystpcpy(s, "POLLNVAL|");
23034f9b3eeSRoland Mainz
23134f9b3eeSRoland Mainz /* Remove trailling '|' */
23234f9b3eeSRoland Mainz s--;
23334f9b3eeSRoland Mainz if(*s=='|')
23434f9b3eeSRoland Mainz *s='\0';
23534f9b3eeSRoland Mainz }
23634f9b3eeSRoland Mainz
23734f9b3eeSRoland Mainz #undef getconf
23834f9b3eeSRoland Mainz #define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0)
239*b30d1939SAndy Fiddaman
b_poll(int argc,char * argv[],Shbltin_t * context)240*b30d1939SAndy Fiddaman extern int b_poll(int argc, char *argv[], Shbltin_t *context)
24134f9b3eeSRoland Mainz {
24234f9b3eeSRoland Mainz Namval_t *np;
243*b30d1939SAndy Fiddaman Shell_t *shp = context->shp;
24434f9b3eeSRoland Mainz char *varname;
24534f9b3eeSRoland Mainz int n;
24634f9b3eeSRoland Mainz int fd;
24734f9b3eeSRoland Mainz nfds_t numpollfd = 0;
24834f9b3eeSRoland Mainz int i;
24934f9b3eeSRoland Mainz char *s;
25034f9b3eeSRoland Mainz double timeout = -1.;
25134f9b3eeSRoland Mainz char buff[PATH_MAX*2+1]; /* enogth to hold two variable names */
25234f9b3eeSRoland Mainz char *eventarrayname = NULL;
25334f9b3eeSRoland Mainz
25434f9b3eeSRoland Mainz while (n = optget(argv, sh_optpoll)) switch (n)
25534f9b3eeSRoland Mainz {
25634f9b3eeSRoland Mainz case 't':
25734f9b3eeSRoland Mainz case 'T':
25834f9b3eeSRoland Mainz errno = 0;
259*b30d1939SAndy Fiddaman timeout = strtod(opt_info.arg, (char **)NULL);
26034f9b3eeSRoland Mainz if (errno != 0)
26134f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "%s: invalid timeout", opt_info.arg);
26234f9b3eeSRoland Mainz
26334f9b3eeSRoland Mainz /* -t uses seconds, -T milliseconds */
26434f9b3eeSRoland Mainz if (n == 't')
26534f9b3eeSRoland Mainz timeout *= 1000.;
26634f9b3eeSRoland Mainz break;
26734f9b3eeSRoland Mainz case 'e':
26834f9b3eeSRoland Mainz eventarrayname = opt_info.arg;
26934f9b3eeSRoland Mainz break;
27034f9b3eeSRoland Mainz case ':':
27134f9b3eeSRoland Mainz errormsg(SH_DICT, 2, "%s", opt_info.arg);
27234f9b3eeSRoland Mainz break;
27334f9b3eeSRoland Mainz case '?':
27434f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
27534f9b3eeSRoland Mainz break;
27634f9b3eeSRoland Mainz }
27734f9b3eeSRoland Mainz argc -= opt_info.index;
27834f9b3eeSRoland Mainz argv += opt_info.index;
27934f9b3eeSRoland Mainz if(argc!=1)
28034f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
28134f9b3eeSRoland Mainz
28234f9b3eeSRoland Mainz varname = argv[0];
28334f9b3eeSRoland Mainz
28434f9b3eeSRoland Mainz Namval_t *array_np, *array_np_sub;
28534f9b3eeSRoland Mainz const char *subname;
28634f9b3eeSRoland Mainz
28734f9b3eeSRoland Mainz array_np = nv_open(varname, shp->var_tree, NV_NOFAIL|NV_NOADD);
28834f9b3eeSRoland Mainz if (!array_np)
28934f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "cannot find array variable %s", varname);
29034f9b3eeSRoland Mainz if(!nv_isattr(array_np, NV_ARRAY))
29134f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "variable %s is not an array", varname);
29234f9b3eeSRoland Mainz
29334f9b3eeSRoland Mainz /* Count number of array elememts. We need to do it "manually" to
29434f9b3eeSRoland Mainz * handle sparse indexed and associative arrays */
29534f9b3eeSRoland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
29634f9b3eeSRoland Mainz array_np_sub = array_np;
29734f9b3eeSRoland Mainz do
29834f9b3eeSRoland Mainz {
29934f9b3eeSRoland Mainz if (!(subname=nv_getsub(array_np_sub)))
30034f9b3eeSRoland Mainz break;
30134f9b3eeSRoland Mainz numpollfd++;
30234f9b3eeSRoland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
30334f9b3eeSRoland Mainz
30434f9b3eeSRoland Mainz #ifdef __GNUC__
30534f9b3eeSRoland Mainz /*
30634f9b3eeSRoland Mainz * Allocate stack space via |alloca()| for gcc builds since ctfconvert
30734f9b3eeSRoland Mainz * is unable to handle VLAs from gcc. We need this until CR #6379193
30834f9b3eeSRoland Mainz * is fixed.
30934f9b3eeSRoland Mainz */
31034f9b3eeSRoland Mainz struct pollfd *pollfd = alloca(sizeof(struct pollfd)*(numpollfd+1));
31134f9b3eeSRoland Mainz #else
31234f9b3eeSRoland Mainz /* We must allocate one more entry with VLA with zero elements do not work with all compilers */
31334f9b3eeSRoland Mainz struct pollfd pollfd[numpollfd+1];
31434f9b3eeSRoland Mainz #endif /* __GNUC__ */
31534f9b3eeSRoland Mainz
31634f9b3eeSRoland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
31734f9b3eeSRoland Mainz array_np_sub = array_np;
31834f9b3eeSRoland Mainz i = 0;
31934f9b3eeSRoland Mainz do
32034f9b3eeSRoland Mainz {
32134f9b3eeSRoland Mainz if (!(subname=nv_getsub(array_np_sub)))
32234f9b3eeSRoland Mainz break;
32334f9b3eeSRoland Mainz
32434f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL|NV_NOADD, "%s[%s].fd", varname, subname);
32534f9b3eeSRoland Mainz if (!np)
32634f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd %s[%s].fd", varname, subname);
32734f9b3eeSRoland Mainz fd = (int)nv_getnum(np);
32834f9b3eeSRoland Mainz if (fd < 0 || fd > OPEN_MAX)
32934f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "invalid pollfd fd %d", fd);
33034f9b3eeSRoland Mainz nv_close(np);
33134f9b3eeSRoland Mainz pollfd[i].fd = fd;
33234f9b3eeSRoland Mainz
33334f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL|NV_NOADD, "%s[%s].events", varname, subname);
33434f9b3eeSRoland Mainz if (!np)
33534f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd %s[%s].events", varname, subname);
33634f9b3eeSRoland Mainz
33734f9b3eeSRoland Mainz s = nv_getval(np);
33834f9b3eeSRoland Mainz if (!s)
33934f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd events value");
34034f9b3eeSRoland Mainz pollfd[i].events = poll_strtoevents(s);
34134f9b3eeSRoland Mainz nv_close(np);
34234f9b3eeSRoland Mainz
34334f9b3eeSRoland Mainz pollfd[i].revents = 0;
344*b30d1939SAndy Fiddaman
34534f9b3eeSRoland Mainz i++;
34634f9b3eeSRoland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
347*b30d1939SAndy Fiddaman
34834f9b3eeSRoland Mainz n = poll(pollfd, numpollfd, timeout);
34934f9b3eeSRoland Mainz /* FixMe: EGAIN and EINTR may require extra handling */
35034f9b3eeSRoland Mainz if (n < 0)
35134f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "failure");
35234f9b3eeSRoland Mainz
35334f9b3eeSRoland Mainz if (eventarrayname)
35434f9b3eeSRoland Mainz {
35534f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_ARRAY|NV_NOFAIL, "%s", eventarrayname);
35634f9b3eeSRoland Mainz if (!np)
35734f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "couldn't create poll count variable %s", eventarrayname);
35834f9b3eeSRoland Mainz nv_close(np);
35934f9b3eeSRoland Mainz }
36034f9b3eeSRoland Mainz
36134f9b3eeSRoland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
36234f9b3eeSRoland Mainz array_np_sub = array_np;
36334f9b3eeSRoland Mainz i = 0;
36434f9b3eeSRoland Mainz do
36534f9b3eeSRoland Mainz {
36634f9b3eeSRoland Mainz if (!(subname=nv_getsub(array_np_sub)))
36734f9b3eeSRoland Mainz break;
368*b30d1939SAndy Fiddaman
36934f9b3eeSRoland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL, "%s[%s].revents", varname, subname);
37034f9b3eeSRoland Mainz if (!np)
37134f9b3eeSRoland Mainz errormsg(SH_DICT, ERROR_system(1), "couldn't create pollfd %s[%s].revents", varname, subname);
37234f9b3eeSRoland Mainz
37334f9b3eeSRoland Mainz poll_eventstostr(buff, pollfd[i].revents);
374*b30d1939SAndy Fiddaman
37534f9b3eeSRoland Mainz nv_putval(np, buff, 0);
37634f9b3eeSRoland Mainz nv_close(np);
377*b30d1939SAndy Fiddaman
37834f9b3eeSRoland Mainz if (eventarrayname && pollfd[i].revents)
37934f9b3eeSRoland Mainz {
38034f9b3eeSRoland Mainz sprintf(buff, "%s+=( '%s' )", eventarrayname, subname);
38134f9b3eeSRoland Mainz sh_trap(buff, 0);
38234f9b3eeSRoland Mainz }
383*b30d1939SAndy Fiddaman
38434f9b3eeSRoland Mainz i++;
38534f9b3eeSRoland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
386*b30d1939SAndy Fiddaman
38734f9b3eeSRoland Mainz nv_close(array_np);
388*b30d1939SAndy Fiddaman
38934f9b3eeSRoland Mainz return(0);
39034f9b3eeSRoland Mainz }
391