Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/bin/sh Extended functionality of the trap builtin, whic...



details:   https://anonhg.NetBSD.org/src/rev/2b697b661339
branches:  netbsd-1-5
changeset: 490898:2b697b661339
user:      wulf <wulf%NetBSD.org@localhost>
date:      Sat Mar 17 10:21:33 2001 +0000

description:
Extended functionality of the trap builtin, which now closely follows
POSIX recommendations.

        - trap now accepts signal names and signal numbers
          e.g. INT, SIGINT, 2
        - added option -l that outputs a list of valid signals
        - added signal EXIT to list of valid signals
        - a `-' in the action part will reset specified signal to their
          default behaviour
        - changed standard output format to make it suitable as an input
          to another shell that achieves the same trapping results

diffstat:

 bin/sh/sh.1   |  48 ++++++++++++++++++++++++++----
 bin/sh/trap.c |  91 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 124 insertions(+), 15 deletions(-)

diffs (204 lines):

diff -r 1ecf053ef0af -r 2b697b661339 bin/sh/sh.1
--- a/bin/sh/sh.1       Fri Mar 16 19:53:57 2001 +0000
+++ b/bin/sh/sh.1       Sat Mar 17 10:21:33 2001 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: sh.1,v 1.33.4.3 2000/09/21 21:32:35 phil Exp $
+.\"    $NetBSD: sh.1,v 1.33.4.4 2001/03/17 10:21:33 wulf Exp $
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -1365,23 +1365,57 @@
 .Ic shift
 does nothing.
 .It Xo trap
+.Op Fl l
+.Xc
+.It Xo trap
 .Op Ar action
 .Ar signal...
 .Xc
 Cause the shell to parse and execute action when any of the specified
-signals are received. The signals are specified by signal number. If
+signals are received. The signals are specified by signal number or as
+the name of the signal.
+If
 .Ar signal
 is
 .Li 0 ,
 the action is executed when the shell exits.
 .Ar action
-may be null or omitted; the former causes the specified signal to be
-ignored and the latter causes the default action to be taken. When the
-shell forks off a subshell, it resets trapped (but not ignored) signals to
-the default action. The
+may be null, which cause the specified signals to be ignored.
+With
+.Ar action
+omitted or set to `-' the specified signals are set to their default action.
+When the shell forks off a subshell, it resets trapped (but not ignored)
+signals to the default action. The
 .Ic trap
 command has no effect on signals that were
-ignored on entry to the shell.
+ignored on entry to the shell. 
+Issuing
+.Ic trap
+with option
+.Ar -l
+will print a list of valid signal names.
+.Ic trap
+without any arguments cause it to write a list of signals and their
+associated action to the standard output in a format that is suitable
+as an input to the shell that achieves the same trapping results.
+.Pp
+Examples:
+.Pp
+.Dl trap
+.Pp
+List trapped signals and their corresponding action
+.Pp
+.Dl trap -l
+.Pp
+Print a list of valid signals
+.Pp
+.Dl trap '' SIGINT QUIT tstp 30
+.Pp
+Ignore signals INT QUIT TSTP USR1
+.Pp
+.Dl trap date INT
+.Pp
+Print date upon receiving signal INT
 .It type Op Ar name ...
 Interpret each name as a command and print the resolution of the command
 search. Possible resolutions are:
diff -r 1ecf053ef0af -r 2b697b661339 bin/sh/trap.c
--- a/bin/sh/trap.c     Fri Mar 16 19:53:57 2001 +0000
+++ b/bin/sh/trap.c     Sat Mar 17 10:21:33 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.24 2000/05/22 10:18:47 elric Exp $  */
+/*     $NetBSD: trap.c,v 1.24.4.1 2001/03/17 10:21:34 wulf Exp $       */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "@(#)trap.c     8.5 (Berkeley) 6/5/95";
 #else
-__RCSID("$NetBSD: trap.c,v 1.24 2000/05/22 10:18:47 elric Exp $");
+__RCSID("$NetBSD: trap.c,v 1.24.4.1 2001/03/17 10:21:34 wulf Exp $");
 #endif
 #endif /* not lint */
 
@@ -85,6 +85,53 @@
 int pendingsigs;                       /* indicates some signal received */
 
 static int getsigaction __P((int, sig_t *));
+static int signame_to_signum __P((const char *));
+void printsignals __P((void));
+
+/*
+ * return the signal number described by `p' (as a number or a name)
+ * or -1 if it isn't one
+ */
+
+static int
+signame_to_signum(p)
+       const char *p;
+{
+       int i;
+
+       if (is_number(p))
+               return number(p);
+
+       if (strcasecmp(p, "exit") == 0 )
+               return 0;
+       
+       if (strncasecmp(p, "sig", 3) == 0)
+               p += 3;
+
+       for (i = 0; i < NSIG; ++i)
+               if (strcasecmp (p, sys_signame[i]) == 0)
+                       return i;
+       return -1;
+}
+
+/*
+ * Print a list of valid signal names
+ */
+void
+printsignals(void)
+{
+       int n;
+
+       out1str("EXIT ");
+
+       for (n = 1; n < NSIG; n++) {
+               out1fmt("%s", sys_signame[n]);
+               if ((n == NSIG/2) ||  n == (NSIG - 1))
+                       out1str("\n");
+               else
+                       out1c(' ');
+       }
+}
 
 /*
  * The trap builtin.
@@ -102,24 +149,52 @@
        if (argc <= 1) {
                for (signo = 0 ; signo <= NSIG ; signo++) {
                        if (trap[signo] != NULL)
-                               out1fmt("%d: %s\n", signo, trap[signo]);
+                               out1fmt("trap -- '%s' %s\n", trap[signo],
+                                   (signo) ? sys_signame[signo] : "EXIT");
                }
                return 0;
        }
        ap = argv + 1;
-       if (is_number(*ap))
-               action = NULL;
-       else
-               action = *ap++;
+
+       action = NULL;
+
+       if (strcmp(*ap, "--") == 0)
+               if (*++ap == NULL)
+                       return 0;
+
+       if (signame_to_signum(*ap) == -1) {
+               if ((*ap)[0] =='-') {
+                       if ((*ap)[1] == NULL)
+                               ap++;
+                       else if ((*ap)[1] == 'l' && (*ap)[2] == NULL) {
+                               printsignals();
+                               return 0;
+                       }
+                       else
+                               error("bad option %s\n", *ap);
+               }
+               else
+                       action = *ap++;
+       }
+
        while (*ap) {
-               if ((signo = number(*ap)) < 0 || signo > NSIG)
+               if (is_number(*ap))
+                       signo = number(*ap);
+               else
+                       signo = signame_to_signum(*ap);
+
+               if (signo < 0 || signo > NSIG)
                        error("%s: bad trap", *ap);
+
                INTOFF;
                if (action)
                        action = savestr(action);
+
                if (trap[signo])
                        ckfree(trap[signo]);
+
                trap[signo] = action;
+
                if (signo != 0)
                        setsignal(signo);
                INTON;



Home | Main Index | Thread Index | Old Index