--- shell.c +++ shell.c 2011-03-08 16:46:50.201047812 +0000 @@ -261,6 +261,9 @@ static const struct { { (char *)0x0, Int, (int *)0x0, (char **)0x0 } }; +volatile procenv_t terminating_now; +volatile sig_atomic_t jump_with_sig; + /* These are extern so execute_simple_command can set them, and then longjmp back to main to execute a shell script, instead of calling main () again and resulting in indefinite, possibly fatal, stack @@ -379,6 +382,20 @@ main (argc, argv, env) if (code) exit (2); + /* Catch signals here */ + if (setjmp (terminating_now)) + { + int sig = jump_with_sig; + terminating_signal = 0; /* keep macro from re-testing true. */ + run_exit_trap (); + if (interactive_shell && sig != SIGABRT) + maybe_save_shell_history (); + set_signal_handler (sig, SIG_DFL); + kill (getpid (), sig); + _exit(0); + } + jump_with_sig = 0; + xtrace_init (); #if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS) --- sig.c +++ sig.c 2011-03-08 16:48:26.707926125 +0000 @@ -503,10 +503,6 @@ termsig_sighandler (sig) /* XXX - should this also trigger when interrupt_immediately is set? */ if (terminate_immediately) { -#if defined (HISTORY) - /* XXX - will inhibit history file being written */ - history_lines_this_session = 0; -#endif terminate_immediately = 0; termsig_handler (sig); } @@ -514,6 +510,9 @@ termsig_sighandler (sig) SIGRETURN (0); } +extern volatile procenv_t terminating_now; +extern volatile sig_atomic_t jump_with_sig; + void termsig_handler (sig) int sig; @@ -551,9 +550,10 @@ termsig_handler (sig) loop_level = continuing = breaking = funcnest = 0; executing_list = comsub_ignore_return = return_catch_flag = 0; - run_exit_trap (); - set_signal_handler (sig, SIG_DFL); - kill (getpid (), sig); + terminating_signal = 0; /* keep macro from re-testing true. */ + + jump_with_sig = sig; + longjmp(terminating_now, 1); } /* What we really do when SIGINT occurs. */