Hi!

----

Attached (as "astksh_20130913_poll1_update004.diff.txt") is the (long
awaited) update for the poll(1) builtin.

* Changes:
- Mostly code cleanup
- use of "bool" in the "events" variable is now mandatory to simplify some code
- poll(1) now has a -s option (similar to sleep(1)) to exit when
poll(2) was interupted by a signal or similar event. poll(1) (like
poll(2)) will return an error, but with exit code 2 instead of exit
code 1 as for normal errors

Comments/rants/etc. welcome...

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) [email protected]
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)
diff -r -u original/src/cmd/ksh93/bltins/poll.c 
build_poll/src/cmd/ksh93/bltins/poll.c
--- src/cmd/ksh93/bltins/poll.c 2013-04-11 21:48:39.000000000 +0200
+++ src/cmd/ksh93/bltins/poll.c 2013-09-16 23:52:21.140525532 +0200
@@ -1,7 +1,7 @@
 /***********************************************************************
 *                                                                      *
 *               This software is part of the ast package               *
-*          Copyright (c) 2007-2012 AT&T Intellectual Property          *
+*          Copyright (c) 2012-2013 AT&T Intellectual Property          *
 *                      and is licensed under the                       *
 *                 Eclipse Public License, Version 1.0                  *
 *                    by AT&T Intellectual Property                     *
@@ -40,7 +40,7 @@
 
 static
 const char sh_optpoll[] =
-"[-?\n@(#)$Id: poll (AT&T Labs Research) 2012-08-16 $\n]"
+"[-?\n@(#)$Id: poll (AT&T Labs Research) 2013-09-14 $\n]"
 "[-author?Roland Mainz <[email protected]>]"
 "[-license?http://www.eclipse.org/org/documents/epl-v10.html]";
 "[+NAME? poll - input/output multiplexing]"
@@ -110,7 +110,7 @@
                "This flag is only valid in the \brevents\b compound "
                "variable; it is not used in the \bevents\b "
                "compound variable.]"
-   "}"
+       "}"
 "]"
 
 "[+?If the value fd is less than 0, events is ignored and "
@@ -146,17 +146,17 @@
        "to other types of file is unspecified.]"
 
 "[+?The poll utility supports sockets.]"
-#ifdef __SunOS
-"[+?The poll utility may be used on Solaris on directory fds of "
+
+"[+?The poll utility may be used on Solaris/Illumos on directory fds of "
        "/proc/$pid/ to get a \bpollhup='true'\b when the process quits.]"
-#endif
+
 "[+?A file descriptor for a socket that is listening for connections "
        "will indicate that it is ready for reading, once connections "
        "are available. A file descriptor for a socket that "
        "is connecting asynchronously will indicate that it is ready "
        "for writing, once a connection has been established.]"
  
-"[+?Regular files always poll TRUE for reading and writing.]"
+"[+?Regular files always poll 'true' for reading and writing.]"
 
 "[e:eventarray]:[fdcount?Upon successful completion, an indexed array "
        "of strings is returned which contains a list of array "
@@ -164,7 +164,8 @@
 "[S!:pollsfio?Look into sfio streams for buffered information and set "
        "pollin/pollout to reflect sfio stream state.]"
 "[R:pollttyraw?Put tty connections into raw mode when polling. The "
-       "fd is returned to tty cooked mode before poll(1) exits.]"
+       "fd is returned to tty cooked mode before \bpoll\b(1) exits.]"
+"[s:sleep?Sleep until a signal, poll event or a timeout is received.]"
 "[t:timeout]:[seconds?Timeout in seconds. If the value timeout is 0, "
        "poll returns immediately. If the value of timeout is -1, "
        "poll blocks until a requested event occurs or until the "
@@ -185,6 +186,10 @@
        "may appear in the \brevents\b compound variable even if "
        "they were not requested in \bevents\b.]"
 
+       "[+?It is recommended to use the \bbool\b type for the \bevents\b "
+       "variables (it can currently not be enforced for "
+       "backwards-compatibility reasons but may be done in the future).]"
+
        "[+?Using the value of variables in \brevents\b which are "
        "not set in \bevents\b can be done by putting a '-' suffix "
        "after the variable name, e.g. use "
@@ -192,19 +197,30 @@
        "\bar[x]].revents.pollhup\b or an empty string if the variable "
        "was not set.]"
 
+       "[+?If any of the \bpoll*\b variables in \bevents\b uses the "
+       "\b_Bool\b type all \bpoll*\b variables in \revents\b will be "
+       "of type \b_Bool\b, too.]"
+
        "[+?Like \bpoll\b(2) it is legal to poll on the same fd in "
        "multiple entries, for exanple to listen for different events "
        "or to allow multiple callers to pool their poll lists "
        "together into one \bpoll\b(1) call.]"
 "}"
 
+"[+KNOWN BUGS?]{"
+       "[+?Multidimensional (typeset -a ar=( [4]][16]]=... )) indexed "
+       "arrays are currently not supported.]"
+"}"
+
 /* quoting: ']' must be quoted as "]]" and '?' must be quoted as "//" */
 "[+EXAMPLES?]{"
        "[+?The following example will wait for 10 seconds for input "
        "on fd 0, variable \bp[fd0]].revents.pollin\b will be 'true' "
        "or 'false' depening on whether the stream 0 is ready for "
        "reading:]{"
-               "[+?compound -A p=( [fd0]]=( fd=0 events=( pollin='true' ) ) ) 
; poll -t10 p ; print -v p]"
+               "[+?compound -A p=( [fd0]]=( integer fd=0 ; compound events=( 
bool pollin='true' ) ) ) ; "
+               "poll -t10 p ; "
+               "print -v p]"
        "}"
 
        "[+?The following example will wait for 2 seconds for input "
@@ -212,7 +228,11 @@
        "\bp[0]].revents.pollhup\b will be 'true' after polling ends "
        "because there is both input data available and the end of "
        "the stream was reached:]{"
-               "[+?printf '\\n' | ksh -c 'compound -a p=( ( fd=0 events=( 
pollin=\"true\" pollhup=\"true\" ) ) ) ; poll -t2 p ; print -v p']"
+               "[+?printf '\\n' | "
+               "ksh -c 'compound -a p=( ( integer fd=0 ; "
+               "compound events=( bool pollin=\"true\" pollhup=\"true\" ) ) ) 
; "
+               "poll -t2 p ; "
+               "print -v p']"
        "}"
 "}"
 
@@ -231,9 +251,39 @@
        vsnprintf(varnamebuff, sizeof(varnamebuff), namefmt, ap);
        va_end(ap);
        
-       return nv_open(varnamebuff, dict, flags);
+       return(nv_open(varnamebuff, dict, flags));
+}
+
+
+static
+bool nv_is_bool_t(Namval_t *np)
+{
+       Namval_t        *nv;
+       const char      *np_tn; /* type name */
+
+       nv=nv_type(np);
+       if (!nv)
+               return(false);
+       np_tn=nv->nvname;
+       if (!np_tn)
+               return(false);
+       if (strcmp(np_tn, "_Bool"))
+               return(false);
+       return(true);
+}
+
+
+static
+Namval_t *nv_get_bool_t(Shell_t *shp)
+{
+       Namval_t *b;
+       b = nv_search("_Bool", shp->bltin_tree,0);
+       if (!b)
+               return(NULL);
+       return(nv_type(b));
 }
 
+
 /* Name/value mapping table for POLL*-flags */
 struct pollflagnamemap
 {
@@ -300,9 +350,19 @@
        int eventvar_found;
 };
 
+typedef struct State_s                  /* program state                */
+{
+       Shbltin_t       *context;
+       Shell_t         *shp;
+       Namval_t        *bool_t;        /* handle to the _Bool type */
+       bool            eagain;
+       int             poll_errno;     /* errno returned by |poll()| */
+} State_t;
+
+
 /* poll on given |fds| data and retry after EINTR/EAGAIN while adjusting 
timeout */
 static
-int poll_loop(Shbltin_t* context, struct pollfd *fds, nfds_t nfds, int timeout)
+int poll_loop(State_t *state, struct pollfd *fds, nfds_t nfds, int timeout)
 {
 /* nanoseconds to milliseconds */
 #define TIME_NS2MS(t) ((t)/(1000UL*1000UL))
@@ -324,98 +384,109 @@
                do
                {
                        while(((n = poll(fds, nfds, timeout)) < 0) &&
-                               ((errno == EINTR) || (errno == EAGAIN)) &&
-                               (!context->sigset))
-                               errno=0;
-
-                       timeout_ns=timeout_ns-(tmxgettime()-starttime);
-                       timeout=TIME_NS2MS(timeout_ns);
-               } while((timeout > 0) && (!context->sigset));
+                               (((errno == EINTR) || (errno == EAGAIN)) && 
state->eagain) &&
+                               (!state->context->sigset))
+                               errno = 0;
+                       state->poll_errno = errno;
+
+                       timeout_ns = timeout_ns-(tmxgettime()-starttime);
+                       timeout = TIME_NS2MS(timeout_ns);
+               } while((timeout > 0) && (!state->context->sigset));
        }
        else
        {
                while(((n = poll(fds, nfds, timeout)) < 0) &&
-                       ((errno == EINTR) || (errno == EAGAIN)) &&
-                       (!context->sigset))
-                       errno=0;
+                       (((errno == EINTR) || (errno == EAGAIN)) && 
state->eagain) &&
+                       (!state->context->sigset))
+                       errno = 0;
+               state->poll_errno = errno;
        }
-       return n;
+       return(n);
 }
 
 
 /* get ".poll*"-variables in "ar[i].events" and store data in |currpollfd| and 
|currps| */
 static
-bool get_compound_revents(Shell_t *shp, const char *parrayname, struct 
pollstat *currps, struct pollfd *currpollfd)
+bool get_compound_revents(State_t *state, const char *parrayname, struct 
pollstat *currps, struct pollfd *currpollfd)
 {
-       const char      *subname=currps->array_subscript;
+       const char      *subname        = currps->array_subscript;
        Namval_t        *np;
        int             fd;
        int             pi;
+       bool            success         = true;
 
-       np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD, 
"%s[%s].fd", parrayname, subname);
+       np = nv_open_fmt(state->shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD, 
"%s[%s].fd", parrayname, subname);
        if (!np)
        {
                errormsg(SH_DICT, ERROR_ERROR, "missing pollfd %s[%s].fd", 
parrayname, subname);
-               return false;
+               return(false);
        }
        fd = (int)nv_getnum(np);
        nv_close(np);
+
+       /* fd==-1 means "ignore entry" */
        if ((fd < -1) || (fd > OPEN_MAX))
        {
                errormsg(SH_DICT, ERROR_ERROR, "invalid pollfd %s[%s].fd %d", 
parrayname, subname, fd);
-               return false;
+               return(false);
        }
        currpollfd->fd = fd;
 
-       np = nv_open_fmt(shp->var_tree, 
NV_VARNAME|NV_COMVAR|NV_NOFAIL|NV_NOADD, "%s[%s].events", parrayname, subname);
+       np = nv_open_fmt(state->shp->var_tree, 
NV_VARNAME|NV_COMVAR|NV_NOFAIL|NV_NOADD, "%s[%s].events", parrayname, subname);
        if (!np)
        {
                errormsg(SH_DICT, ERROR_ERROR, "missing pollfd %s[%s].events", 
parrayname, subname);
-               return false;
+               return(false);
        }
        nv_close(np);
 
-       currpollfd->events=0;
-       currpollfd->revents=0;
-       currps->eventvar_found=0;
+       currpollfd->events              = 0;
+       currpollfd->revents             = 0;
+       currps->eventvar_found          = 0;
+
        for (pi=0 ; pfnm[pi].name != NULL ; pi++)
        {
-               const char *s;
-
-               np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_NOADD, 
"%s[%s].events.%s", parrayname, subname, pfnm[pi].name);
+               np = nv_open_fmt(state->shp->var_tree, 
NV_VARNAME|NV_NOFAIL|NV_NOADD, "%s[%s].events.%s", parrayname, subname, 
pfnm[pi].name);
                if (!np)
+               {
+                       /* ignore this, it may be a sparse array */
                        continue;
+               }
 
-               currps->eventvar_found |= pfnm[pi].flag;
-               s=nv_getval(np);
-               if (s != NULL)
+               if (nv_is_bool_t(np))
                {
-                       if (!strcmp(s, "true"))
+                       currps->eventvar_found |= pfnm[pi].flag;
+                       if (((bool)nv_getnum(np)) == true)
                                currpollfd->events |= pfnm[pi].flag;
-                       else if (!strcmp(s, "false"))
-                               ;
-                       else
-                               errormsg(SH_DICT, ERROR_ERROR, "invalid boolean 
value % in variable %s[%s].events", s, parrayname, subname);
+
                }
+               else
+               {
+                       errormsg(SH_DICT, ERROR_ERROR, "%s[%s].events.%s is not 
of type _Bool", parrayname, subname, pfnm[pi].name);
+                       success = false;
+               }
+
                nv_close(np);
        }
 
-       return true;
+       return(success);
 }
 
+
 /* set ".poll*"-variables in "ar[i].revents" per data in |currpollfd| and 
|currps| */
 static
-void set_compound_revents(Shell_t *shp, const char *parrayname, struct 
pollstat *currps, struct pollfd *currpollfd)
+bool set_compound_revents(State_t *state, const char *parrayname, struct 
pollstat *currps, struct pollfd *currpollfd)
 {
-       const char *subname=currps->array_subscript;
-       Namval_t *np;
-       int pi;
+       const char      *subname        = currps->array_subscript;
+       Namval_t        *np;
+       int             pi;
+       bool            success         = true;
 
-       np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_COMVAR, 
"%s[%s].revents", parrayname, subname);
+       np = nv_open_fmt(state->shp->var_tree, NV_VARNAME|NV_NOFAIL|NV_COMVAR, 
"%s[%s].revents", parrayname, subname);
        if (!np)
        {
                errormsg(SH_DICT, ERROR_ERROR, "could not create pollfd 
%s[%s].revents", parrayname, subname);
-               return;
+               return(false);
        }
        nv_setvtree(np); /* make "revents" really a compound variable */
        nv_close(np);
@@ -429,21 +500,29 @@
                if ((currps->eventvar_found & pfnm[pi].flag) ||
                        ((currpollfd->revents & (POLLHUP|POLLNVAL|POLLERR)) & 
pfnm[pi].flag))
                {
-                       np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_NOFAIL, 
"%s[%s].revents.%s", parrayname, subname, pfnm[pi].name);
+                       np = nv_open_fmt(state->shp->var_tree, 
NV_VARNAME|NV_NOFAIL, "%s[%s].revents.%s", parrayname, subname, pfnm[pi].name);
                        if (!np)
+                       {
+                               success = false;
                                continue;
+                       }
 
+                       nv_settype(np, state->bool_t, 0);
                        nv_putval(np, ((currpollfd->revents & 
pfnm[pi].flag)?"true":"false"), 0);
+
                        nv_close(np);
                }
        }
+
+       return(success);
 }
 
+
 /* |main()| for poll(1) builtin */
 extern
 int b_poll(int argc, char *argv[], Shbltin_t* context)
 {
-       Shell_t         *shp = sh_contexttoshell(context);
+       State_t         state;
        Namval_t        *np,
                        *array_np,
                        *array_np_sub;
@@ -453,7 +532,7 @@
                        *subname,               /* current subscript */
                        *s;
        int             n;
-       nfds_t          numpollfd = 0;          /* number of entries to poll */
+       nfds_t          numpollfd       = 0;    /* number of entries to poll */
        int             i,
                        j;
        double          timeout         = -1.;
@@ -467,6 +546,11 @@
                        *currps;                /* current |pollstat| we are 
working on */
        int             retval          = 0;    /* return value of builtin */
 
+       state.context           = context;
+       state.shp               = sh_contexttoshell(context);
+       state.eagain            = true;
+       state.poll_errno        = 0;
+
        while (n = optget(argv, sh_optpoll)) switch (n)
        {
                case 't':
@@ -476,12 +560,15 @@
                                errormsg(SH_DICT, ERROR_system(1), "%s: invalid 
timeout", opt_info.arg);
 
                        /* -t uses seconds */
-                       if (timeout >=0)
+                       if (timeout >= 0)
                                timeout *= 1000.;
                        break;
                case 'e':
                        eventarrayname = opt_info.arg;
                        break;
+               case 's':
+                       state.eagain=opt_info.num?false:true;
+                       break;
                case 'S':
                        pollsfio=opt_info.num?true:false;
                        break;
@@ -502,11 +589,15 @@
 
        parrayname = argv[0];
 
+       state.bool_t = nv_get_bool_t(state.shp);
+       if (!state.bool_t)
+               errormsg(SH_DICT, ERROR_system(1), "internal error: _Bool type 
not found");
+
        strstk = stkopen(0);
        if (!strstk)
                errormsg(SH_DICT, ERROR_system(1), e_nospace);
 
-       array_np = nv_open(parrayname, shp->var_tree, 
NV_VARNAME|NV_NOFAIL|NV_NOADD);
+       array_np = nv_open(parrayname, state.shp->var_tree, 
NV_VARNAME|NV_NOFAIL|NV_NOADD);
        if (!array_np)
        {
                stkclose(strstk);
@@ -551,7 +642,7 @@
        i = 0;
        do
        {
-               if (!(subname=nv_getsub(array_np_sub)))
+               if (!(subname = nv_getsub(array_np_sub)))
                        break;
 
                pollstat[i].array_subscript=stkcopy(strstk, subname);
@@ -561,14 +652,14 @@
                        goto done_error;
                }
 
-               if (!get_compound_revents(shp, parrayname, &pollstat[i], 
&pollfd[i]))
+               if (!get_compound_revents(&state, parrayname, &pollstat[i], 
&pollfd[i]))
                        goto done_error;
 
                i++;
        } while(array_np_sub && nv_nextsub(array_np_sub));
 
        nv_close(array_np);
-       array_np=NULL;
+       array_np = NULL;
 
        /*
         * If sfio handles fds we need to check whether there are
@@ -592,11 +683,11 @@
 
                for (i=0 ; i < numpollfd ; i++)
                {
-                       currps=&pollstat[i];
-                       fd=pollfd[i].fd;
+                       currps = &pollstat[i];
+                       fd = pollfd[i].fd;
                        
-                       currps->sfio.sfd=(fd>=0)?sh_fd2sfio(shp, fd):NULL;
-                       currps->sfio.flags=0;
+                       currps->sfio.sfd = (fd>=0)?sh_fd2sfio(state.shp, 
fd):NULL;
+                       currps->sfio.flags = 0;
                        if (currps->sfio.sfd!=NULL)
                        {
                                /* Only add |currps->sfio.sfd| to the
@@ -618,7 +709,7 @@
                                                break;
                                }
                                if (j == num_sfd)
-                                       sfd[num_sfd++]=currps->sfio.sfd;
+                                       sfd[num_sfd++] = currps->sfio.sfd;
                        }
                }
 
@@ -640,7 +731,7 @@
                                for (j=0 ; j < numpollfd ; j++)
                                {
                                        if (pollstat[j].sfio.sfd == sfd[i])
-                                               
pollstat[j].sfio.flags=sfpoll_flags;
+                                               pollstat[j].sfio.flags = 
sfpoll_flags;
                                }
                        }
                }
@@ -651,7 +742,7 @@
         */
        if (eventarrayname)
        {
-               np = nv_open_fmt(shp->var_tree, NV_VARNAME|NV_ARRAY|NV_NOFAIL, 
"%s", eventarrayname);
+               np = nv_open_fmt(state.shp->var_tree, 
NV_VARNAME|NV_ARRAY|NV_NOFAIL, "%s", eventarrayname);
                if (!np)
                {
                        errormsg(SH_DICT, ERROR_ERROR, "could not create 
eventarray variable %s", eventarrayname);
@@ -659,6 +750,10 @@
                }
 
                nv_close(np);
+
+               /* Clear array */
+               sfsprintf(buff, sizeof(buff), "%s=()", eventarrayname);
+               sh_trap(state.shp, buff, 0);
        }
 
        /*
@@ -670,8 +765,8 @@
 
                for (i=0 ; i < numpollfd ; i++)
                {
-                       fd=pollfd[i].fd;
-                       if ((fd >=0) && (shp->fdstatus[fd]&IOTTY))
+                       fd = pollfd[i].fd;
+                       if ((fd >= 0) && (state.shp->fdstatus[fd]&IOTTY))
                                tty_raw(fd, 1);
                }
        }
@@ -679,7 +774,7 @@
        /*
         * ... then poll for events...
         */
-       n = poll_loop(context, pollfd, numpollfd, timeout);
+       n = poll_loop(&state, pollfd, numpollfd, timeout);
 
        /* 
         * ... and restore the tty's to "cooked" mode
@@ -690,17 +785,19 @@
 
                for (i=0 ; i < numpollfd ; i++)
                {
-                       fd=pollfd[i].fd;
-                       if ((fd >=0) && (shp->fdstatus[fd]&IOTTY))
+                       fd = pollfd[i].fd;
+                       if ((fd >= 0) && (state.shp->fdstatus[fd]&IOTTY))
                                tty_cooked(fd);
                }
        }
 
        if (n < 0)
        {
+               retval = (state.poll_errno==EAGAIN || 
state.poll_errno==EINTR)?2:1;
+               errno = state.poll_errno;
                /* |ERROR_system(0)| won't quit the builtin */
                errormsg(SH_DICT, ERROR_system(0), "poll(2) failure");
-               retval=1;
+
        }
 
        /*
@@ -717,20 +814,21 @@
                                pollfd[i].revents |= POLLOUT;
                }
 
-               set_compound_revents(shp, parrayname, &pollstat[i], &pollfd[i]);
+               if (!set_compound_revents(&state, parrayname, &pollstat[i], 
&pollfd[i]))
+                       retval = 1;
 
                /* Add array index to eventarray if this pollfd entry had any 
events */
                if (eventarrayname && pollfd[i].revents)
                {
                        sfsprintf(buff, sizeof(buff), "%s+=( '%s' )", 
eventarrayname, pollstat[i].array_subscript);
-                       sh_trap(shp, buff, 0);
+                       sh_trap(state.shp, buff, 0);
                }
        }
        
        goto done;
 
 done_error:
-       retval=1;
+       retval = 1;
 done:
        if (array_np)
                nv_close(array_np);
diff -r -u original/src/cmd/ksh93/tests/builtin_poll.sh 
build_poll/src/cmd/ksh93/tests/builtin_poll.sh
--- src/cmd/ksh93/tests/builtin_poll.sh 2013-05-11 22:23:48.000000000 +0200
+++ src/cmd/ksh93/tests/builtin_poll.sh 2013-09-16 22:32:11.545232157 +0200
@@ -1,26 +1,7 @@
 ########################################################################
 #                                                                      #
 #               This software is part of the ast package               #
-#          Copyright (c) 1982-2013 AT&T Intellectual Property          #
-#                      and is licensed under the                       #
-#                 Eclipse Public License, Version 1.0                  #
-#                    by AT&T Intellectual Property                     #
-#                                                                      #
-#                A copy of the License is available at                 #
-#          http://www.eclipse.org/org/documents/epl-v10.html           #
-#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
-#                                                                      #
-#              Information and Software Systems Research               #
-#                            AT&T Research                             #
-#                           Florham Park NJ                            #
-#                                                                      #
-#                  David Korn <[email protected]>                   #
-#                                                                      #
-########################################################################
-########################################################################
-#                                                                      #
-#               This software is part of the ast package               #
-#                 Copyright (c) 2009-2012 Roland Mainz                 #
+#                 Copyright (c) 2009-2013 Roland Mainz                 #
 #                      and is licensed under the                       #
 #                 Eclipse Public License, Version 1.0                  #
 #                    by AT&T Intellectual Property                     #
@@ -35,7 +16,7 @@
 ########################################################################
 
 #
-# Copyright (c) 2009, 2012, Roland Mainz. All rights reserved.
+# Copyright (c) 2009, 2013, Roland Mainz. All rights reserved.
 #
 
 #
@@ -70,8 +51,8 @@
 {
        compound d1=(
                compound -A u=(
-                       [y]=( integer fd=5 ; compound events=( pollin='true' ) 
revents=() )
-                       [x]=( integer fd=5 ; compound events=( pollin='true' ) 
revents=() )
+                       [y]=( integer fd=5 ; compound events=( bool 
pollin='true' ) revents=() )
+                       [x]=( integer fd=5 ; compound events=( bool 
pollin='true' ) revents=() )
                )
        )
 
@@ -88,7 +69,7 @@
 
        # test 2:
        unset d1.res
-       d1.u[z]=( integer fd=5 ; compound events=( pollout='true' ) revents=() )
+       d1.u[z]=( integer fd=5 ; compound events=( bool pollout='true' ) 
revents=() )
 
        print -C d1 >'testdata.cpv'
        $SHELL -o errexit -c 'builtin poll ; read -C <"testdata.cpv" d1 ; { 
poll -e d1.res -t 5. d1.u ; } 5<"/dev/null" 5>"/dev/null" ; print -C d1 
>"testdata.cpv"' >'log.txt' 2>&1 || err_exit "poll returned non-zero exit code 
$?"
@@ -120,19 +101,19 @@
                                $'integer i maxfd=$(getconf "OPEN_MAX")\n'
                                $'(( maxfd-=10 )) # space for 
stdin/stdout/stderr/dirfd\n'
                                $'for (( i=0 ; i < maxfd ; i++ )) ; do\n'
-                               $'      pl[$((i*17))]=( fd=0 events=( 
pollin=true ) )\n'
+                               $'      pl[$((i*17))]=( fd=0 events=( bool 
pollin=true ) )\n'
                                $'done\n'
                                $'poll -R -t2 pl\n'
                                $'print -v pl\n'
                                $'print "OK"\n'
                        )
-                       
expected_output_pattern='~(E)([[:space:]]*?\([[:space:]]*?\[.+\]=\([[:space:]]*?events=\([[:space:]]*?pollin=true[[:space:]]*?\)[[:space:]]*?fd=0[[:space:]]*?revents=\([[:space:]]*?pollhup=true[[:space:]]*?pollin=true[[:space:]]*?\)[[:space:]]*?\)[[:space:]]*?\)[[:space:]]*?)+OK'
+                       
expected_output_pattern='~(E)([[:space:]]*?\([[:space:]]*?\[.+\]=\([[:space:]]*?events=\([[:space:]]*?(_Bool|)[[:space:]]*?pollin=true[[:space:]]*?\)[[:space:]]*?fd=0[[:space:]]*?revents=\([[:space:]]*?(_Bool|)[[:space:]]*?pollhup=true[[:space:]]*?(_Bool|)[[:space:]]*?pollin=true[[:space:]]*?\)[[:space:]]*?\)[[:space:]]*?\)[[:space:]]*?)+OK'
                )
                (
                        name='sparse_type_array1'
                        typeset -r -a script=(
                                $'builtin poll\n'
-                               $'typeset -T p_t=( typeset -l -i fd ; \n'
+                               $'typeset -T p_t=( typeset fd=-1 ; \n' # fixme: 
This should be "integer fd=-1" but ast-ksh.2013-09-13 crashes
                                # fixme: In theory we only have to list the 
events we want
                                # in the compound variable "events" ... and the 
same events
                                # plus pollerr, pollnval and pollup in 
"revents" (since
@@ -141,8 +122,8 @@
                                # which triggers fatal errors in case we try to 
read a
                                # non-existing type variable member - see
                                # 
http://marc.info/?l=ast-developers&m=134526131905059&w=2
-                               $'      compound events=(  typeset pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
-                               $'      compound revents=( typeset pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
+                               $'      compound events=(  bool pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
+                               $'      compound revents=( bool pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
                                $'      function pinit { _.fd=$1 ; 
_.events.pollin=true ; } ;\n'
                                $')\n'
                                $'compound c ; p_t -a c.pl\n'
@@ -158,13 +139,13 @@
                                $'print -v c\n'
                                $'print "OK"\n'
                        )
-                       
expected_output_pattern='~(Xlr)\([[:space:]]+?p_t[[:space:]]+?-a[[:space:]]+?pl=\([[:space:]]+?([[:space:]]+?\[[[:alnum:]]+\]=\([[:space:]]+?typeset[[:space:]]+?-l[[:space:]]+?-i[[:space:]]+?fd=0[[:space:]]+?events=\((([^\x28\x29]+?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?pollhup=false[^\x28\x29]+?))[[:space:]]+?\)[[:space:]]+?revents=\((([^\x28\x29]+?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?pollhup=true[^\x28\x29]+?))\)[[:space:]]+?\)[[:space:]]+?)+?[[:space:]]+?\)[[:space:]]+?\)[[:space:]]+?OK'
+                       
expected_output_pattern='~(Xlr)\([[:space:]]+?p_t[[:space:]]+?-a[[:space:]]+?pl=\([[:space:]]+?([[:space:]]+?\[[[:alnum:]]+\]=\(([[:space:]]+?typeset[[:space:]]+?-l[[:space:]]+?-i)*?[[:space:]]+?fd=0[[:space:]]+?events=\((([^\x28\x29]+?(_Bool|)[[:space:]]*?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?(_Bool|)[[:space:]]*?pollhup=false[^\x28\x29]+?))[[:space:]]+?\)[[:space:]]+?revents=\((([^\x28\x29]+?(_Bool|)[[:space:]]*?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?(_Bool|)[[:space:]]*?pollhup=true[^\x28\x29]+?))\)[[:space:]]+?\)[[:space:]]+?)+?[[:space:]]+?\)[[:space:]]+?\)[[:space:]]+?OK'
                )
                (
                        name='associative_type_array1'
                        typeset -r -a script=(
                                $'builtin poll\n'
-                               $'typeset -T p_t=( typeset -l -i fd ; \n'
+                               $'typeset -T p_t=( typeset fd=-1 ; \n' # fixme: 
This should be "integer fd=-1" but ast-ksh.2013-09-13 crashes
                                # fixme: In theory we only have to list the 
events we want
                                # in the compound variable "events" ... and the 
same events
                                # plus pollerr, pollnval and pollup in 
"revents" (since
@@ -173,8 +154,8 @@
                                # which triggers fatal errors in case we try to 
read a
                                # non-existing type variable member - see
                                # 
http://marc.info/?l=ast-developers&m=134526131905059&w=2
-                               $'      compound events=(  typeset pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
-                               $'      compound revents=( typeset pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
+                               $'      compound events=(  bool pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
+                               $'      compound revents=( bool pollin=false 
pollpri=false pollout=false pollrdnorm=false pollwrnorm=false pollrdband=false 
pollwrband=false pollmsg=false pollremove=false pollrdhup=false pollerr=false 
pollhup=false pollnval=false ; )\n'
                                $'      function pinit { _.fd=$1 ; 
_.events.pollin=true ; } ;\n'
                                $')\n'
                                $'compound c ; p_t -A c.pl\n'
@@ -190,7 +171,7 @@
                                $'print -v c\n'
                                $'print "OK"\n'
                        )
-                       
expected_output_pattern='~(Xlr)\([[:space:]]+?p_t[[:space:]]+?-A[[:space:]]+?pl=\([[:space:]]+?([[:space:]]+?\[[[:alnum:]]+\]=\([[:space:]]+?typeset[[:space:]]+?-l[[:space:]]+?-i[[:space:]]+?fd=0[[:space:]]+?events=\((([^\x28\x29]+?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?pollhup=false[^\x28\x29]+?))[[:space:]]+?\)[[:space:]]+?revents=\((([^\x28\x29]+?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?pollhup=true[^\x28\x29]+?))\)[[:space:]]+?\)[[:space:]]+?)+?[[:space:]]+?\)[[:space:]]+?\)[[:space:]]+?OK'
+                       
expected_output_pattern='~(Xlr)\([[:space:]]+?p_t[[:space:]]+?-A[[:space:]]+?pl=\([[:space:]]+?([[:space:]]+?\[[[:alnum:]]+\]=\(([[:space:]]+?typeset[[:space:]]+?-l[[:space:]]+?-i)*?[[:space:]]+?fd=0[[:space:]]+?events=\((([^\x28\x29]+?(_Bool|)[[:space:]]*?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?(_Bool|)[[:space:]]*?pollhup=false[^\x28\x29]+?))[[:space:]]+?\)[[:space:]]+?revents=\((([^\x28\x29]+?(_Bool|)[[:space:]]*?pollin=true[^\x28\x29]+?)&([^\x28\x29]+?(_Bool|)[[:space:]]*?pollhup=true[^\x28\x29]+?))\)[[:space:]]+?\)[[:space:]]+?)+?[[:space:]]+?\)[[:space:]]+?\)[[:space:]]+?OK'
                )
        )
 
@@ -219,17 +200,16 @@
        integer i
        typeset testname
 cat >'poll_circus.sh' <<EOF
+# fixme: add com.kornshell.tests.builtin_poll.fifo_circus1 namespace
+# namespaces unfortunately don't work with "shcomp" from ast-ksh.2013-09-13
 typeset -T circus_t=(
        typeset fifo_name
-       integer in_fd
-       integer out_fd
+       integer in_fd=-1
+       integer out_fd=-1
 
        function fifo_init
        {
                integer pid
-               # fixme: we can't assign fd directly because ast-ksh.2012-08-13 
has a bug
-               # with "redirect"
-               integer fd
 
                _.fifo_name="\$1"
                rm -f "\${_.fifo_name}"
@@ -241,14 +221,12 @@
                { redirect {dummy}<"\${_.fifo_name}" ; for (( ;; )) ; do sleep 
15 ; done ; } &
                (( pid=\$! ))
 
-               redirect {fd}>"\${_.fifo_name}"
-               (( _.out_fd=fd ))
+               redirect {_.out_fd}>"\${_.fifo_name}"
                #printf '%s: outfd=%d\n' "\${_.fifo_name}" _.out_fd
 
                kill \$pid ; wait \$pid 2>'/dev/null'
 
-               redirect {fd}<"\${_.fifo_name}"
-               (( _.in_fd=fd ))
+               redirect {_.in_fd}<"\${_.fifo_name}"
                #printf '%s: infd=%d\n' "\${_.fifo_name}" _.in_fd
 
                return 0
@@ -278,9 +256,9 @@
        compound -A pollfd
        for name in "\${!ar[@]}" ; do
                subname="fifo_\${name}_in"
-               pollfd[\${subname}]=( fd=\${ar[\${name}].in_fd}  events=( 
pollin='true'  pollerr='false' pollhup='false' pollnval='false' ) revents=() )
+               pollfd[\${subname}]=( integer fd=\${ar[\${name}].in_fd}  ; 
compound events=( bool pollin='true'  pollerr='false' pollhup='false' 
pollnval='false' ) revents=() )
                subname="fifo_\${name}_out"
-               pollfd[\${subname}]=( fd=\${ar[\${name}].out_fd} events=( 
pollout='true' pollerr='false' pollhup='false' pollnval='false' ) revents=() )
+               pollfd[\${subname}]=( integer fd=\${ar[\${name}].out_fd} ; 
compound events=( bool pollout='true' pollerr='false' pollhup='false' 
pollnval='false' ) revents=() )
        done
 
        # main event loop       
@@ -293,36 +271,36 @@
                        up="\$name"
        
                        subname="fifo_\${name}_in"
-                       if \${pollfd[\${subname}].revents.pollin}    ; then 
printf '%sI+' "\${up}" ; else printf '...' ; fi
-                       if \${pollfd[\${subname}].revents.pollhup}   ; then 
printf '%sIH' "\${up}" ; else printf '...' ; fi
-                       if \${pollfd[\${subname}].revents.pollerr}   ; then 
printf '%sIE' "\${up}" ; else printf '...' ; fi
-                       if \${pollfd[\${subname}].revents.pollnval}  ; then 
printf '%sIN' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollin   ))  ; then 
printf '%sI+' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollhup  ))  ; then 
printf '%sIH' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollerr  ))  ; then 
printf '%sIE' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollnval ))  ; then 
printf '%sIN' "\${up}" ; else printf '...' ; fi
                        subname="fifo_\${name}_out"
-                       if \${pollfd[\${subname}].revents.pollout}   ; then 
printf '%sO+' "\${up}" ; else printf '...' ; fi
-                       if \${pollfd[\${subname}].revents.pollhup}   ; then 
printf '%sOH' "\${up}" ; else printf '...' ; fi
-                       if \${pollfd[\${subname}].revents.pollerr}   ; then 
printf '%sOE' "\${up}" ; else printf '...' ; fi
-                       if \${pollfd[\${subname}].revents.pollnval}  ; then 
printf '%sON' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollout  ))  ; then 
printf '%sO+' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollhup  ))  ; then 
printf '%sOH' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollerr  ))  ; then 
printf '%sOE' "\${up}" ; else printf '...' ; fi
+                       if (( pollfd[\${subname}].revents.pollnval ))  ; then 
printf '%sON' "\${up}" ; else printf '...' ; fi
                        printf '|'
                done
                printf '\n'
 
                # pass token around
-               if \${pollfd[fifo_a_in].revents.pollin} && 
\${pollfd[fifo_b_out].revents.pollout}; then
+               if (( pollfd[fifo_a_in].revents.pollin && 
pollfd[fifo_b_out].revents.pollout )) ; then
                        if read -u\${pollfd[fifo_a_in].fd} -N1 x ; then
                                print -u\${pollfd[fifo_b_out].fd} -f "%s" "\$x" 
2>'/dev/null'
                        fi
                fi
-               if \${pollfd[fifo_b_in].revents.pollin} && 
\${pollfd[fifo_c_out].revents.pollout}; then
+               if (( pollfd[fifo_b_in].revents.pollin && 
pollfd[fifo_c_out].revents.pollout )) ; then
                        if read -u\${pollfd[fifo_b_in].fd} -N1 x ; then
                                print -u\${pollfd[fifo_c_out].fd} -f "%s" "\$x" 
2>'/dev/null'
                        fi
                fi
-               if \${pollfd[fifo_c_in].revents.pollin} && 
\${pollfd[fifo_d_out].revents.pollout}; then
+               if (( pollfd[fifo_c_in].revents.pollin && 
pollfd[fifo_d_out].revents.pollout )) ; then
                        if read -u\${pollfd[fifo_c_in].fd} -N1 x ; then
                                print -u\${pollfd[fifo_d_out].fd} -f "%s" "\$x" 
2>'/dev/null'
                        fi
                fi
-               if \${pollfd[fifo_d_in].revents.pollin} && 
\${pollfd[fifo_a_out].revents.pollout}; then
+               if (( pollfd[fifo_d_in].revents.pollin && 
pollfd[fifo_a_out].revents.pollout )) ; then
                        if read -u\${pollfd[fifo_d_in].fd} -N1 x ; then
                                print -u\${pollfd[fifo_a_out].fd} -f "%s" "\$x" 
2>'/dev/null'
                        fi
@@ -331,19 +309,19 @@
                # send HUP around
                # we explicitly do NOT close the file descriptors here
                # to force poll(1) to set revents.pollnval=true
-               if \${pollfd[fifo_a_in].revents.pollhup} ; then
+               if (( pollfd[fifo_a_in].revents.pollhup )) ; then
                        redirect {pollfd[fifo_a_in].fd}<&-;
                        redirect {pollfd[fifo_b_out].fd}<&-;
                fi
-               if \${pollfd[fifo_b_in].revents.pollhup} ; then
+               if (( pollfd[fifo_b_in].revents.pollhup )) ; then
                        redirect {pollfd[fifo_b_in].fd}<&-;
                        redirect {pollfd[fifo_c_out].fd}<&-;
                fi
-               if \${pollfd[fifo_c_in].revents.pollhup} ; then
+               if (( pollfd[fifo_c_in].revents.pollhup )) ; then
                        redirect {pollfd[fifo_c_in].fd}<&-;
                        redirect {pollfd[fifo_d_out].fd}<&-;
                fi
-               if \${pollfd[fifo_d_in].revents.pollhup} ; then
+               if (( pollfd[fifo_d_in].revents.pollhup )) ; then
                        redirect {pollfd[fifo_d_in].fd}<&-;
                        redirect {pollfd[fifo_a_out].fd}<&-;
                fi
@@ -357,23 +335,26 @@
                # - real applications may just use something like
                # \$ unset pollfd[fifo_a_in] # to remove the whole
                #   array node
-               \${pollfd[fifo_a_in].revents.pollnval}  && (( 
pollfd[fifo_a_in].fd=-1  ))
-               \${pollfd[fifo_a_out].revents.pollnval} && (( 
pollfd[fifo_a_out].fd=-1 ))
-               \${pollfd[fifo_b_in].revents.pollnval}  && (( 
pollfd[fifo_b_in].fd=-1  ))
-               \${pollfd[fifo_b_out].revents.pollnval} && (( 
pollfd[fifo_b_out].fd=-1 ))
-               \${pollfd[fifo_c_in].revents.pollnval}  && (( 
pollfd[fifo_c_in].fd=-1  ))
-               \${pollfd[fifo_c_out].revents.pollnval} && (( 
pollfd[fifo_c_out].fd=-1 ))
-               \${pollfd[fifo_d_in].revents.pollnval}  && (( 
pollfd[fifo_d_in].fd=-1  ))
-               \${pollfd[fifo_d_out].revents.pollnval} && (( 
pollfd[fifo_d_out].fd=-1 ))
+               (( pollfd[fifo_a_in].revents.pollnval  && 
(pollfd[fifo_a_in].fd=-1)  ))
+               (( pollfd[fifo_a_out].revents.pollnval && 
(pollfd[fifo_a_out].fd=-1) ))
+               (( pollfd[fifo_b_in].revents.pollnval  && 
(pollfd[fifo_b_in].fd=-1)  ))
+               (( pollfd[fifo_b_out].revents.pollnval && 
(pollfd[fifo_b_out].fd=-1) ))
+               (( pollfd[fifo_c_in].revents.pollnval  && 
(pollfd[fifo_c_in].fd=-1)  ))
+               (( pollfd[fifo_c_out].revents.pollnval && 
(pollfd[fifo_c_out].fd=-1) ))
+               (( pollfd[fifo_d_in].revents.pollnval  && 
(pollfd[fifo_d_in].fd=-1)  ))
+               (( pollfd[fifo_d_out].revents.pollnval && 
(pollfd[fifo_d_out].fd=-1) ))
 
                # send start token      
                if (( i==0 )) ; then
                        # Use the Euro symbol (\u[20ac]) if the locale
-                       # uses a UTF-8 encoding
-                       typeset -r utf8_euro_char1=\$'\u[20ac]'
-                       typeset -r utf8_euro_char2=\$'\342\202\254'
-                       if (( (\${#utf8_euro_char1} == 1) && 
(\${#utf8_euro_char2} == 1) )) ; then
-                               print -u\${pollfd[fifo_a_out].fd} -f '\u[20ac]'
+                       # supports it.
+                       # \$'\u[20ac-]' (note the trailing '-') returns an
+                       # empty string if the unicode codepoint 0x20ac
+                       # cannot be represented in the current locle
+                       if [[ \$'\u[20ac-]' != '' ]] ; then
+                               [[ "\${ wc -C <<<\$'\u[20ac-]' ;}" == 
~(Er)[[:space:]]+2 ]] || \
+                                       print -u2 'ASSERT: Unicode 0x20ac is 
not a character'
+                               print -u\${pollfd[fifo_a_out].fd} -f 
\$'\u[20ac]'
                        else
                                print -u\${pollfd[fifo_a_out].fd} -f 'X'
                        fi
@@ -398,6 +379,7 @@
 builtin mkfifo
 builtin poll
 builtin rm
+builtin wc
 
 main
 exit $?
@@ -445,6 +427,7 @@
 
 # run tests
 builtin poll   || { err_exit 'poll builtin not found.'; exit 1; }
+builtin rm     || { err_exit 'rm builtin not found.'; exit 1; }
 builtin rmdir  || { err_exit 'rmdir builtin not found.'; exit 1; }
 
 test1
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers

Reply via email to