Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: SUGGESTION: kill -l could show numbers, too (+CLD vs CHLD)
- X-seq: zsh-workers 20572
- From: Peter Stephenson <pws@xxxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Re: SUGGESTION: kill -l could show numbers, too (+CLD vs CHLD)
- Date: Sat, 20 Nov 2004 19:29:27 +0000
- In-reply-to: <27996.1100858392@xxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20041118145208.GD13232@xxxxxxxx> <20310.1100793917@xxxxxxx> <20041118163901.GD4511@sc> <6451.1100798576@xxxxxxx> <27996.1100858392@xxxxxxx>
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 <pws@xxxxxxxxxxxxxxxxxxxxxxxx>
Work: pws@xxxxxxx
Web: http://www.pwstephenson.fsnet.co.uk
Messages sorted by:
Reverse Date,
Date,
Thread,
Author