34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/***********************************************************************
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 1982-2009 AT&T Intellectual Property *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* and is licensed under the *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Common Public License, Version 1.0 *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* by AT&T Intellectual Property *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* A copy of the License is available at *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* http://www.opensource.org/licenses/cpl1.0.txt *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Information and Software Systems Research *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* AT&T Research *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Florham Park NJ *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Roland Mainz <roland.mainz@nrubsig.org> *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz***********************************************************************/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#pragma prototyped
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <shell.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <stdio.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <stdbool.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <option.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <stk.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <tm.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include "name.h"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#undef nv_isnull
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifndef SH_DICT
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# define SH_DICT "libshell"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <poll.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef __GNUC__
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <alloca.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* __GNUC__ */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define sh_contexttoshb(context) ((Shbltin_t*)(context))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define sh_contexttoshell(context) ((context)?(sh_contexttoshb(context)->shp):(NULL))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic const char sh_optpoll[] =
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[-?\n@(#)$Id: poll (AT&T Labs Research) 2009-05-14 $\n]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[-author?Roland Mainz <roland.mainz@nrubsig.org]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+NAME? poll - input/output multiplexing]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+DESCRIPTION?The poll command provides applications with a mechanism "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "for multiplexing input/output over a set of file descriptors. "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "For each member of the array variable \bvar\b, "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "poll examines the given file descriptor in the subscript \b.fd\b "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "for the event(s) specified in the subscript \b.events\b."
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "The poll command identifies those file descriptors on which an "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "application can read or write data, or on which certain events have "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "occurred.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?The \bvar\b argument specifies the file descriptors to be examined "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "and the events of interest for each file descriptor. "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "It is a array of structured variables with one member for each open "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "file descriptor of interest. The array's members contain the following "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "subscripts:]{"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+?\b.fd\b # file descriptor]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+?\b.events\b # requested events]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+?\b.revents\b # returned event]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "}"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?The \bfd\b variable specifies an open file descriptor and the "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "\bevents\b and \brevents\b members are strings constructed from "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "a concaternation of the following event flags, seperated by '|':]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "{ "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLIN?Data other than high priority data may be "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "read without blocking. For STREAMS, this "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "flag is set in revents even if the message "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "is of zero length.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLRDNORM?Normal data (priority band equals 0) may be "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "read without blocking. For STREAMS, this "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "flag is set in revents even if the message "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "is of zero length.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLRDBAND?Data from a non-zero priority band may be "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "read without blocking. For STREAMS, this "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "flag is set in revents even if the message "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "is of zero length.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLPRI?High priority data may be received without "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "blocking. For STREAMS, this flag is set in "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "revents even if the message is of zero "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "length.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLOUT?Normal data (priority band equals 0) may be "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "written without blocking.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLWRNORM?The same as POLLOUT.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLWRBAND?Priority data (priority band > 0) may be "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "written. This event only examines bands "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "that have been written to at least once.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLERR?An error has occurred on the device or "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "stream. This flag is only valid in the "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "revents bitmask; it is not used in the "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "events member.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLHUP?A hangup has occurred on the stream. This "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "event and POLLOUT are mutually exclusive; a "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "stream can never be writable if a hangup has "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "occurred. However, this event and POLLIN, "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ", POLLRDBAND, or POLLPRI are not "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "mutually exclusive. This flag is only valid "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "in the revents bitmask; it is not used in "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "the events member.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+POLLNVAL?The specified fd value does not belong to an "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "open file. This flag is only valid in the "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "revents member; it is not used in the events "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "member.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "}"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?If the value fd is less than 0, events is ignored and "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "revents is set to 0 in that entry on return from poll.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?The results of the poll query are stored in the revents "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "member in the \bvar\b structure. POLL*-strings are set in the \brevents\b "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "variable to indicate which of the requested events are true. "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "If none are true, the \brevents\b will be an empty string when "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "the poll command returns. The event flags "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "POLLHUP, POLLERR, and POLLNVAL are always set in \brevents\b "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "if the conditions they indicate are true; this occurs even "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "though these flags were not present in events.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?If none of the defined events have occurred on any selected "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "file descriptor, poll waits at least timeout milliseconds "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "for an event to occur on any of the selected file descriptors. "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "On a computer where millisecond timing accuracy is not "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "available, timeout is rounded up to the nearest legal value "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "available on that system. If the value timeout is 0, poll "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "returns immediately. If the value of timeout is -1, poll "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "blocks until a requested event occurs or until the call is "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "interrupted.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?The poll function supports regular files, terminal and "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "pseudo-terminal devices, STREAMS-based files, FIFOs and "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "pipes. The behavior of poll on elements of fds that refer "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "to other types of file is unspecified.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?The poll function supports sockets.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?A file descriptor for a socket that is listening for connections "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "will indicate that it is ready for reading, once connections "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "are available. A file descriptor for a socket that "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "is connecting asynchronously will indicate that it is ready "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "for writing, once a connection has been established.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?Regular files always poll TRUE for reading and writing.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[e:eventarray]:[fdcount?Upon successful completion, an indexed array "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "of strings is returned which contains a list of array subscripts "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "in the poll array which received events.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[t:timeout]:[seconds?Timeout in seconds. If the value timeout is 0, "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "poll returns immediately. If the value of timeout is -1, poll "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "blocks until a requested event occurs or until the call is "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "interrupted.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[T:mtimeout]:[milliseconds?Timeout in milliseconds. If the value timeout is 0, "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "poll returns immediately. If the value of timeout is -1, poll "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "blocks until a requested event occurs or until the call is "
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "interrupted.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"\nvar\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+EXIT STATUS?]{"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+0?Success.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "[+>0?An error occurred.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"}"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+SEE ALSO?\bopen\b(1),\btmpfile\b(1),\bdup\b(1),\bclose\b(1),\bpoll\b(2)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * |mystpcpy| - like |strcpy()| but returns the end of the buffer
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * Copy string s2 to s1. s1 must be large enough.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * return s1-1 (position of string terminator ('\0') in destnation buffer).
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzchar *mystpcpy(char *s1, const char *s2)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (*s1++ = *s2++)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (s1-1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzNamval_t *nv_open_fmt(Dt_t *dict, int flags, const char *namefmt, ...)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char varnamebuff[PATH_MAX];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz va_list ap;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz va_start(ap, namefmt);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz vsnprintf(varnamebuff, sizeof(varnamebuff), namefmt, ap);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz va_end(ap);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return nv_open(varnamebuff, dict, flags);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint poll_strtoevents(const char *str)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int events = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLIN")) events |= POLLIN;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLRDNORM")) events |= POLLRDNORM;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLRDBAND")) events |= POLLRDBAND;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLPRI")) events |= POLLPRI;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLOUT")) events |= POLLOUT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLWRNORM")) events |= POLLWRNORM;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLWRBAND")) events |= POLLWRBAND;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLERR")) events |= POLLERR;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLHUP")) events |= POLLHUP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strstr(str, "POLLNVAL")) events |= POLLNVAL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return events;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzvoid poll_eventstostr(char *s, int events)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *s='\0';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!events)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLIN) s=mystpcpy(s, "POLLIN|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLRDNORM) s=mystpcpy(s, "POLLRDNORM|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLRDBAND) s=mystpcpy(s, "POLLRDBAND|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLPRI) s=mystpcpy(s, "POLLPRI|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLOUT) s=mystpcpy(s, "POLLOUT|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLWRNORM) s=mystpcpy(s, "POLLWRNORM|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLWRBAND) s=mystpcpy(s, "POLLWRBAND|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLERR) s=mystpcpy(s, "POLLERR|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLHUP) s=mystpcpy(s, "POLLHUP|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (events & POLLNVAL) s=mystpcpy(s, "POLLNVAL|");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* Remove trailling '|' */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s--;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*s=='|')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *s='\0';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#undef getconf
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define getconf(x) strtol(astconf(x,NiL,NiL),NiL,0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzextern int b_poll(int argc, char *argv[], void *extra)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namval_t *np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Shell_t *shp = sh_contexttoshell(extra);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *varname;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int n;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int fd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nfds_t numpollfd = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int i;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz double timeout = -1.;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char buff[PATH_MAX*2+1]; /* enogth to hold two variable names */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char *eventarrayname = NULL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (n = optget(argv, sh_optpoll)) switch (n)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 't':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'T':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errno = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz timeout = strtod(opt_info.arg, (char **)NULL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (errno != 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "%s: invalid timeout", opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* -t uses seconds, -T milliseconds */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (n == 't')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz timeout *= 1000.;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'e':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz eventarrayname = opt_info.arg;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case ':':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, 2, "%s", opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case '?':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argc -= opt_info.index;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argv += opt_info.index;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(argc!=1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz varname = argv[0];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namval_t *array_np, *array_np_sub;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz const char *subname;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz array_np = nv_open(varname, shp->var_tree, NV_NOFAIL|NV_NOADD);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!array_np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "cannot find array variable %s", varname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!nv_isattr(array_np, NV_ARRAY))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "variable %s is not an array", varname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* Count number of array elememts. We need to do it "manually" to
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * handle sparse indexed and associative arrays */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz array_np_sub = array_np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(subname=nv_getsub(array_np_sub)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz numpollfd++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef __GNUC__
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * Allocate stack space via |alloca()| for gcc builds since ctfconvert
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * is unable to handle VLAs from gcc. We need this until CR #6379193
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * is fixed.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct pollfd *pollfd = alloca(sizeof(struct pollfd)*(numpollfd+1));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* We must allocate one more entry with VLA with zero elements do not work with all compilers */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct pollfd pollfd[numpollfd+1];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* __GNUC__ */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz array_np_sub = array_np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz i = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(subname=nv_getsub(array_np_sub)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL|NV_NOADD, "%s[%s].fd", varname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd %s[%s].fd", varname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fd = (int)nv_getnum(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fd < 0 || fd > OPEN_MAX)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "invalid pollfd fd %d", fd);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_close(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pollfd[i].fd = fd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL|NV_NOADD, "%s[%s].events", varname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd %s[%s].events", varname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = nv_getval(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "missing pollfd events value");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pollfd[i].events = poll_strtoevents(s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_close(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pollfd[i].revents = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz i++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = poll(pollfd, numpollfd, timeout);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* FixMe: EGAIN and EINTR may require extra handling */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (n < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "failure");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (eventarrayname)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_ARRAY|NV_NOFAIL, "%s", eventarrayname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "couldn't create poll count variable %s", eventarrayname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_close(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putsub(array_np, NULL, ARRAY_SCAN);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz array_np_sub = array_np;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz i = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(subname=nv_getsub(array_np_sub)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz np = nv_open_fmt(shp->var_tree, NV_NOFAIL, "%s[%s].revents", varname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT, ERROR_system(1), "couldn't create pollfd %s[%s].revents", varname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz poll_eventstostr(buff, pollfd[i].revents);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putval(np, buff, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_close(np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (eventarrayname && pollfd[i].revents)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sprintf(buff, "%s+=( '%s' )", eventarrayname, subname);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_trap(buff, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz i++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while( array_np_sub && nv_nextsub(array_np_sub) );
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_close(array_np);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}