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.
 
 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.
 
 
 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
 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.
 
 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. */
 
 #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)
 
 int
 trap_builtin (list)
@@ -103,6 +107,7 @@ trap_builtin (list)
 
   list_signal_names = display = 0;
   result = EXECUTION_SUCCESS;
 
   list_signal_names = display = 0;
   result = EXECUTION_SUCCESS;
+
   reset_internal_getopt ();
   while ((opt = internal_getopt (list, "lp")) != -1)
     {
   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)
   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;
   else
     {
       char *first_arg;
@@ -163,6 +172,16 @@ trap_builtin (list)
            operation = REVERT;
        }
 
            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);
       while (list)
        {
          sig = decode_signal (list->word->word, opt);
@@ -188,6 +207,8 @@ trap_builtin (list)
                    switch (sig)
                      {
                      case SIGINT:
                    switch (sig)
                      {
                      case SIGINT:
+                       /* XXX - should we do this if original disposition
+                          was SIG_IGN? */
                        if (interactive)
                          set_signal_handler (SIGINT, sigint_sighandler);
                        else
                        if (interactive)
                          set_signal_handler (SIGINT, sigint_sighandler);
                        else
@@ -229,10 +250,13 @@ showtrap (i)
   char *t, *p, *sn;
 
   p = trap_list[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;
     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. */
   sn = signal_name (i);
   /* Make sure that signals whose names are unknown (for whatever reason)
      are printed as signal numbers. */