From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 835 invoked from network); 21 Nov 2004 07:31:54 -0000 Received: from ns2.primenet.com.au (HELO primenet.com.au) (?cJap5hxZ4j6Ard0iaLM+fOgti2oKAn/F?@203.24.36.3) by ns1.primenet.com.au with SMTP; 21 Nov 2004 07:31:54 -0000 Received: (qmail 21114 invoked from network); 21 Nov 2004 02:29:42 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by proxy.melb.primenet.com.au with SMTP; 21 Nov 2004 02:29:42 -0000 Received: (qmail 34734 invoked from network); 20 Nov 2004 19:22:56 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 20 Nov 2004 19:22:56 -0000 Received: (qmail 15053 invoked by alias); 20 Nov 2004 19:22:42 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 20572 Received: (qmail 15039 invoked from network); 20 Nov 2004 19:22:41 -0000 Received: from unknown (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 20 Nov 2004 19:22:41 -0000 Received: (qmail 34159 invoked from network); 20 Nov 2004 19:21:42 -0000 Received: from cmailg3.svr.pol.co.uk (195.92.195.173) by a.mx.sunsite.dk with SMTP; 20 Nov 2004 19:21:40 -0000 Received: from modem-1.chromis.dialup.pol.co.uk ([62.136.245.1] helo=pwstephenson.fsnet.co.uk) by cmailg3.svr.pol.co.uk with esmtp (Exim 4.41) id 1CVanh-0006V5-FU for zsh-workers@sunsite.dk; Sat, 20 Nov 2004 19:21:39 +0000 Received: by pwstephenson.fsnet.co.uk (Postfix, from userid 501) id C34B38638; Sat, 20 Nov 2004 14:29:29 -0500 (EST) Received: from pwstephenson.fsnet.co.uk (localhost [127.0.0.1]) by pwstephenson.fsnet.co.uk (Postfix) with ESMTP id 778BE862F for ; Sat, 20 Nov 2004 19:29:29 +0000 (GMT) To: zsh-workers@sunsite.dk Subject: Re: SUGGESTION: kill -l could show numbers, too (+CLD vs CHLD) In-reply-to: <27996.1100858392@csr.com> References: <20041118145208.GD13232@gerf.org> <20310.1100793917@csr.com> <20041118163901.GD4511@sc> <6451.1100798576@csr.com> <27996.1100858392@csr.com> Date: Sat, 20 Nov 2004 19:29:27 +0000 From: Peter Stephenson Message-Id: <20041120192929.C34B38638@pwstephenson.fsnet.co.uk> X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: * X-Spam-Status: No, hits=1.5 required=6.0 tests=RCVD_IN_SORBS autolearn=no version=2.63 X-Spam-Hits: 1.5 Peter Stephenson wrote: > I'm working on something to allow variants on input. This is easy > enough for kill, the real killer is function-style traps. The following appears to be Not Completely Broken (TM), although I put some weasel words into the documentation. Index: Doc/Zsh/builtins.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v retrieving revision 1.71 diff -u -r1.71 builtins.yo --- Doc/Zsh/builtins.yo 5 Oct 2004 10:39:43 -0000 1.71 +++ Doc/Zsh/builtins.yo 20 Nov 2004 19:10:32 -0000 @@ -626,6 +626,14 @@ listed. For each var(sig) that is a signal number or a number representing the exit status of a process which was terminated or stopped by a signal the name of the signal is printed. + +On some systems, alternative signal names are allowed for a few signals. +Typical examples are tt(SIGCHLD) and tt(SIGCLD) or tt(SIGPOLL) and +tt(SIGIO), assuming they correspond to the same signal number. tt(kill +-l) will only list the preferred form, however tt(kill -l) var(alt) will +show if the alternative form corresponds to a signal number. For example, +under Linux tt(kill -l IO) and tt(kill -l POLL) both output 29, hence +tt(kill -IO) and tt(kill -POLL) have the same effect. ) findex(let) item(tt(let) var(arg) ...)( @@ -1179,6 +1187,11 @@ example(TRAPDEBUG() { print $LINENO; }) will always print the number zero. + +Alternative signal names are allowed as described under tt(kill) above. +Defining a trap under either name causes any trap under an alternative +name to be removed. However, it is recommended that for consistency +users stick exclusively to one name or another. ) findex(true) cindex(doing nothing, successfully) Index: Src/builtin.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.131 diff -u -r1.131 builtin.c --- Src/builtin.c 21 Oct 2004 00:33:50 -0000 1.131 +++ Src/builtin.c 20 Nov 2004 19:11:34 -0000 @@ -2543,7 +2543,16 @@ /* no flags, so just print */ shfunctab->printnode((HashNode) shf, pflags); } else if (on & PM_UNDEFINED) { - int signum, ok = 1; + int signum = -1, ok = 1; + + if (!strncmp(*argv, "TRAP", 4) && + (signum = getsignum(*argv + 4)) != -1) { + /* + * Because of the possibility of alternative names, + * we must remove the trap explicitly. + */ + removetrapnode(signum); + } /* Add a new undefined (autoloaded) function to the * * hash table with the corresponding flags set. */ @@ -2552,8 +2561,7 @@ shf->funcdef = mkautofn(shf); shfunctab->addnode(shfunctab, ztrdup(*argv), shf); - if (!strncmp(*argv, "TRAP", 4) && - (signum = getsignum(*argv + 4)) != -1) { + if (signum != -1) { if (settrap(signum, shf->funcdef)) { shfunctab->removenode(shfunctab, *argv); shfunctab->freenode((HashNode)shf); @@ -4898,11 +4906,9 @@ queue_signals(); for (sig = 0; sig < VSIGCOUNT; sig++) { if (sigtrapped[sig] & ZSIG_FUNC) { - char fname[20]; HashNode hn; - sprintf(fname, "TRAP%s", sigs[sig]); - if ((hn = shfunctab->getnode(shfunctab, fname))) + if ((hn = gettrapnode(sig, 0))) shfunctab->printnode(hn, 0); DPUTS(!hn, "BUG: I did not find any trap functions!"); } else if (sigtrapped[sig]) { Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.77 diff -u -r1.77 exec.c --- Src/exec.c 29 Oct 2004 10:14:34 -0000 1.77 +++ Src/exec.c 20 Nov 2004 19:12:13 -0000 @@ -3345,6 +3345,12 @@ return 1; } sigtrapped[signum] |= ZSIG_FUNC; + + /* + * Remove the old node explicitly in case it has + * an alternative name + */ + removetrapnode(signum); } shfunctab->addnode(shfunctab, ztrdup(s), shf); } Index: Src/jobs.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v retrieving revision 1.35 diff -u -r1.35 jobs.c --- Src/jobs.c 22 Oct 2004 19:38:59 -0000 1.35 +++ Src/jobs.c 20 Nov 2004 19:12:34 -0000 @@ -1819,6 +1819,36 @@ return retval; } +#if defined(SIGCHLD) && defined(SIGCLD) +#if SIGCHLD == SIGCLD +#define ALT_SIGS 1 +#endif +#endif +#if defined(SIGPOLL) && defined(SIGIO) +#if SIGPOLL == SIGIO +#define ALT_SIGS 1 +#endif +#endif + +#ifdef ALT_SIGS +const struct { + const char *name; + int num; +} alt_sigs[] = { +#if defined(SIGCHLD) && defined(SIGCLD) +#if SIGCHLD == SIGCLD + { "CLD", SIGCLD }, +#endif +#endif +#if defined(SIGPOLL) && defined(SIGIO) +#if SIGPOLL == SIGIO + { "IO", SIGIO }, +#endif +#endif + { NULL, 0 } +}; +#endif + /* kill: send a signal to a process. The process(es) may be specified * * by job specifier (see above) or pid. A signal, defaulting to * * SIGTERM, may be specified by name or number, preceded by a dash. */ @@ -1847,6 +1877,18 @@ for (sig = 1; sig <= SIGCOUNT; sig++) if (!cstrpcmp(sigs + sig, &signame)) break; +#ifdef ALT_SIGS + if (sig > SIGCOUNT) { + int i; + + for (i = 0; alt_sigs[i].name; i++) + if (!cstrpcmp(&alt_sigs[i].name, &signame)) + { + sig = alt_sigs[i].num; + break; + } + } +#endif if (sig > SIGCOUNT) { zwarnnam(nam, "unknown signal: SIG%s", signame, 0); @@ -1908,6 +1950,18 @@ break; if (*signame == '0' && !signame[1]) sig = 0; +#ifdef ALT_SIGS + if (sig > SIGCOUNT) { + int i; + + for (i = 0; alt_sigs[i].name; i++) + if (!strcmp(alt_sigs[i].name, signame)) + { + sig = alt_sigs[i].num; + break; + } + } +#endif if (sig > SIGCOUNT) { zwarnnam(nam, "unknown signal: SIG%s", signame, 0); zwarnnam(nam, "type kill -l for a List of signals", NULL, 0); @@ -1964,6 +2018,81 @@ return returnval < 126 ? returnval : 1; } +/* Get a signal number from a string */ + +/**/ +mod_export int +getsignum(char *s) +{ + int x, i; + + /* check for a signal specified by number */ + x = atoi(s); + if (idigit(*s) && x >= 0 && x < VSIGCOUNT) + return x; + + /* search for signal by name */ + for (i = 0; i < VSIGCOUNT; i++) + if (!strcmp(s, sigs[i])) + return i; + +#ifdef ALT_SIGS + for (i = 0; alt_sigs[i].name; i++) + { + if (!strcmp(s, alt_sigs[i].name)) + return alt_sigs[i].num; + } +#endif + + /* no matching signal */ + return -1; +} + +/* Get the function node for a trap, taking care about alternative names */ +/**/ +HashNode +gettrapnode(int sig, int ignoredisable) +{ + char fname[20]; + HashNode hn; + HashNode (*getptr)(HashTable ht, char *name); +#ifdef ALT_SIGS + int i; +#endif + if (ignoredisable) + getptr = shfunctab->getnode2; + else + getptr = shfunctab->getnode; + + sprintf(fname, "TRAP%s", sigs[sig]); + if ((hn = getptr(shfunctab, fname))) + return hn; + +#ifdef ALT_SIGS + for (i = 0; alt_sigs[i].name; i++) { + if (alt_sigs[i].num == sig) { + sprintf(fname, "TRAP%s", alt_sigs[i].name); + if ((hn = getptr(shfunctab, fname))) + return hn; + } + } +#endif + + return NULL; +} + +/* Remove a TRAP function under any name for the signal */ + +/**/ +void +removetrapnode(int sig) +{ + HashNode hn = gettrapnode(sig, 1); + if (hn) { + shfunctab->removenode(shfunctab, hn->nam); + shfunctab->freenode(hn); + } +} /* Suspend this shell */ Index: Src/signals.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/signals.c,v retrieving revision 1.32 diff -u -r1.32 signals.c --- Src/signals.c 8 Oct 2004 14:37:31 -0000 1.32 +++ Src/signals.c 20 Nov 2004 19:12:44 -0000 @@ -697,10 +697,8 @@ * Get the old function: this assumes we haven't added * the new one yet. */ - char func[20]; Shfunc shf, newshf = NULL; - sprintf(func, "TRAP%s", sigs[sig]); - if ((shf = (Shfunc)shfunctab->getnode2(shfunctab, func))) { + if ((shf = (Shfunc)gettrapnode(sig, 1))) { /* Copy the node for saving */ newshf = (Shfunc) zalloc(sizeof(*newshf)); newshf->nam = ztrdup(shf->nam); @@ -837,16 +835,15 @@ * That causes a little inefficiency, but a good deal more reliability. */ if (trapped & ZSIG_FUNC) { - char func[20]; - HashNode node; + HashNode node = gettrapnode(sig, 1); - sprintf(func, "TRAP%s", sigs[sig]); /* * As in dosavetrap(), don't call removeshfuncnode() because * that calls back into unsettrap(); */ sigfuncs[sig] = NULL; - node = removehashnode(shfunctab, func); + if (node) + removehashnode(shfunctab, node->nam); unqueue_signals(); return node; @@ -1010,10 +1007,10 @@ runhookdef(BEFORETRAPHOOK, NULL); if (*sigtr & ZSIG_FUNC) { int osc = sfcontext; + HashNode hn = gettrapnode(sig, 0); args = znewlinklist(); - name = (char *) zalloc(5 + strlen(sigs[sig])); - sprintf(name, "TRAP%s", sigs[sig]); + name = ztrdup(hn->nam); zaddlinknode(args, name); sprintf(num, "%d", sig); zaddlinknode(args, num); Index: Src/utils.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/utils.c,v retrieving revision 1.69 diff -u -r1.69 utils.c --- Src/utils.c 21 Oct 2004 00:33:42 -0000 1.69 +++ Src/utils.c 20 Nov 2004 19:13:19 -0000 @@ -3969,27 +3969,6 @@ return err; } -/* Get a signal number from a string */ - -/**/ -mod_export int -getsignum(char *s) -{ - int x, i; - - /* check for a signal specified by number */ - x = atoi(s); - if (idigit(*s) && x >= 0 && x < VSIGCOUNT) - return x; - - /* search for signal by name */ - for (i = 0; i < VSIGCOUNT; i++) - if (!strcmp(s, sigs[i])) - return i; - - /* no matching signal */ - return -1; -} /* Check whether the shell is running with privileges in effect. * * This is the case if EITHER the euid is zero, OR (if the system * -- Peter Stephenson Work: pws@csr.com Web: http://www.pwstephenson.fsnet.co.uk