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 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 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 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 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 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