Bash-4.2 distribution sources and documentation
[platform/upstream/bash.git] / builtins / trap.def
index a8da71d..2119f5b 100644 (file)
@@ -1,7 +1,7 @@
 This file is trap.def, from which is created trap.c.
 It implements the builtin "trap" in Bash.
 
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2010 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -35,7 +35,11 @@ value.  If ARG is the null string each SIGNAL_SPEC is ignored by the
 shell and by the commands it invokes.
 
 If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell.  If
-a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.
+a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.  If
+a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
+script run by the . or source builtins finishes executing.  A SIGNAL_SPEC
+of ERR means to execute ARG each time a command's failure would cause the
+shell to exit when the -e option is enabled.
 
 If no arguments are supplied, trap prints the list of commands associated
 with each signal.
@@ -93,7 +97,7 @@ static int display_traps __P((WORD_LIST *));
 #define REVERT 1               /* Revert to this signals original value. */
 #define IGNORE 2               /* Ignore this signal. */
 
-extern int posixly_correct;
+extern int posixly_correct, subshell_environment;
 
 int
 trap_builtin (list)
@@ -103,6 +107,7 @@ trap_builtin (list)
 
   list_signal_names = display = 0;
   result = EXECUTION_SUCCESS;
+
   reset_internal_getopt ();
   while ((opt = internal_getopt (list, "lp")) != -1)
     {
@@ -126,7 +131,11 @@ trap_builtin (list)
   if (list_signal_names)
     return (sh_chkwrite (display_signal_list ((WORD_LIST *)NULL, 1)));
   else if (display || list == 0)
-    return (sh_chkwrite (display_traps (list)));
+    {
+      initialize_terminating_signals ();
+      get_all_original_signals ();
+      return (sh_chkwrite (display_traps (list)));
+    }
   else
     {
       char *first_arg;
@@ -163,6 +172,16 @@ trap_builtin (list)
            operation = REVERT;
        }
 
+      /* If we're in a command substitution, we haven't freed the trap strings
+        (though we reset the signal handlers).  If we're setting a trap to
+        handle a signal here, free the rest of the trap strings since they
+        don't apply any more. */
+      if (subshell_environment & SUBSHELL_RESETTRAP)
+       {
+         free_trap_strings ();
+         subshell_environment &= ~SUBSHELL_RESETTRAP;
+       }
+
       while (list)
        {
          sig = decode_signal (list->word->word, opt);
@@ -188,6 +207,8 @@ trap_builtin (list)
                    switch (sig)
                      {
                      case SIGINT:
+                       /* XXX - should we do this if original disposition
+                          was SIG_IGN? */
                        if (interactive)
                          set_signal_handler (SIGINT, sigint_sighandler);
                        else
@@ -229,10 +250,13 @@ showtrap (i)
   char *t, *p, *sn;
 
   p = trap_list[i];
-  if (p == (char *)DEFAULT_SIG)
+  if (p == (char *)DEFAULT_SIG && signal_is_hard_ignored (i) == 0)
     return;
+  else if (signal_is_hard_ignored (i))
+    t = (char *)NULL;
+  else
+    t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p);
 
-  t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p);
   sn = signal_name (i);
   /* Make sure that signals whose names are unknown (for whatever reason)
      are printed as signal numbers. */