| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* sig.c - interface for shell signal handlers and signal initialization. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | /* Copyright (C) 1994-2013 Free Software Foundation, Inc.
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |    (at your option) any later version. | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "config.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bashtypes.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H)
 | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #  ifdef _MINIX
 | 
					
						
							|  |  |  | #    include <sys/types.h>
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #include "bashintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include "shell.h"
 | 
					
						
							|  |  |  | #if defined (JOB_CONTROL)
 | 
					
						
							|  |  |  | #include "jobs.h"
 | 
					
						
							|  |  |  | #endif /* JOB_CONTROL */
 | 
					
						
							|  |  |  | #include "siglist.h"
 | 
					
						
							|  |  |  | #include "sig.h"
 | 
					
						
							|  |  |  | #include "trap.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "builtins/common.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | #include "builtins/builtext.h"
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined (READLINE)
 | 
					
						
							|  |  |  | #  include "bashline.h"
 | 
					
						
							| 
									
										
										
										
											2011-11-22 20:00:47 -05:00
										 |  |  | #  include <readline/readline.h>
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HISTORY)
 | 
					
						
							|  |  |  | #  include "bashhist.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern int last_command_exit_value; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | extern int last_command_exit_signal; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | extern int return_catch_flag; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | extern int loop_level, continuing, breaking, funcnest; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | extern int executing_list; | 
					
						
							|  |  |  | extern int comsub_ignore_return; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | extern int parse_and_execute_level, shell_initialized; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | #if defined (HISTORY)
 | 
					
						
							|  |  |  | extern int history_lines_this_session; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-11-22 20:00:47 -05:00
										 |  |  | extern int no_line_editing; | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | extern int wait_signal_received; | 
					
						
							|  |  |  | extern sh_builtin_func_t *this_shell_builtin; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern void initialize_siglist (); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Non-zero after SIGINT. */ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | volatile sig_atomic_t interrupt_state = 0; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | /* Non-zero after SIGWINCH */ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | volatile sig_atomic_t sigwinch_received = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Non-zero after SIGTERM */ | 
					
						
							|  |  |  | volatile sig_atomic_t sigterm_received = 0; | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  | /* Set to the value of any terminating signal received. */ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | volatile sig_atomic_t terminating_signal = 0; | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* The environment at the top-level R-E loop.  We use this in
 | 
					
						
							|  |  |  |    the case of error return. */ | 
					
						
							|  |  |  | procenv_t top_level; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							|  |  |  | /* The signal masks that this shell runs with. */ | 
					
						
							|  |  |  | sigset_t top_level_mask; | 
					
						
							|  |  |  | #endif /* JOB_CONTROL */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* When non-zero, we throw_to_top_level (). */ | 
					
						
							|  |  |  | int interrupt_immediately = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  | /* When non-zero, we call the terminating signal handler immediately. */ | 
					
						
							|  |  |  | int terminate_immediately = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | #if defined (SIGWINCH)
 | 
					
						
							|  |  |  | static SigHandler *old_winch = (SigHandler *)SIG_DFL; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | static void initialize_shell_signals __P((void)); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | initialize_signals (reinit) | 
					
						
							|  |  |  |      int reinit; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   initialize_shell_signals (); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   initialize_job_signals (); | 
					
						
							| 
									
										
										
										
											1997-09-22 20:22:27 +00:00
										 |  |  | #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   if (reinit == 0) | 
					
						
							|  |  |  |     initialize_siglist (); | 
					
						
							| 
									
										
										
										
											1997-09-22 20:22:27 +00:00
										 |  |  | #endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A structure describing a signal that terminates the shell if not
 | 
					
						
							|  |  |  |    caught.  The orig_handler member is present so children can reset | 
					
						
							|  |  |  |    these signals back to their original handlers. */ | 
					
						
							|  |  |  | struct termsig { | 
					
						
							|  |  |  |      int signum; | 
					
						
							|  |  |  |      SigHandler *orig_handler; | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |      int orig_flags; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define NULL_HANDLER (SigHandler *)SIG_DFL
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The list of signals that would terminate the shell if not caught.
 | 
					
						
							|  |  |  |    We catch them, but just so that we can write the history file, | 
					
						
							|  |  |  |    and so forth. */ | 
					
						
							|  |  |  | static struct termsig terminating_signals[] = { | 
					
						
							|  |  |  | #ifdef SIGHUP
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGHUP, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGINT
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGINT, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGILL
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGILL, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGTRAP
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGTRAP, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGIOT
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGIOT, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGDANGER
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGDANGER, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGEMT
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGEMT, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGFPE
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGFPE, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGBUS
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGBUS, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGSEGV
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGSEGV, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGSYS
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGSYS, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGPIPE
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGPIPE, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGALRM
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGALRM, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGTERM
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGTERM, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGXCPU
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGXCPU, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGXFSZ
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGXFSZ, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGVTALRM
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGVTALRM, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #ifdef SIGPROF
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGPROF, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGLOST
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGLOST, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGUSR1
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGUSR1, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SIGUSR2
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | {  SIGUSR2, NULL_HANDLER, 0 }, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define XSIG(x) (terminating_signals[x].signum)
 | 
					
						
							|  |  |  | #define XHANDLER(x) (terminating_signals[x].orig_handler)
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | #define XSAFLAGS(x) (terminating_signals[x].orig_flags)
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | static int termsigs_initialized = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* Initialize signals that will terminate the shell to do some
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |    unwind protection.  For non-interactive shells, we only call | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |    this when a trap is defined for EXIT (0) or when trap is run | 
					
						
							|  |  |  |    to display signal dispositions. */ | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | initialize_terminating_signals () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #if defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							|  |  |  |   struct sigaction act, oact; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (termsigs_initialized) | 
					
						
							|  |  |  |     return; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* The following code is to avoid an expensive call to
 | 
					
						
							|  |  |  |      set_signal_handler () for each terminating_signals.  Fortunately, | 
					
						
							|  |  |  |      this is possible in Posix.  Unfortunately, we have to call signal () | 
					
						
							|  |  |  |      on non-Posix systems for each signal in terminating_signals. */ | 
					
						
							|  |  |  | #if defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  |   act.sa_handler = termsig_sighandler; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   act.sa_flags = 0; | 
					
						
							|  |  |  |   sigemptyset (&act.sa_mask); | 
					
						
							|  |  |  |   sigemptyset (&oact.sa_mask); | 
					
						
							|  |  |  |   for (i = 0; i < TERMSIGS_LENGTH; i++) | 
					
						
							|  |  |  |     sigaddset (&act.sa_mask, XSIG (i)); | 
					
						
							|  |  |  |   for (i = 0; i < TERMSIGS_LENGTH; i++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |       /* If we've already trapped it, don't do anything. */ | 
					
						
							|  |  |  |       if (signal_is_trapped (XSIG (i))) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       sigaction (XSIG (i), &act, &oact); | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |       XHANDLER(i) = oact.sa_handler; | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       XSAFLAGS(i) = oact.sa_flags; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       /* Don't do anything with signals that are ignored at shell entry
 | 
					
						
							|  |  |  | 	 if the shell is not interactive. */ | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |       /* XXX - should we do this for interactive shells, too? */ | 
					
						
							|  |  |  |       if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	  sigaction (XSIG (i), &oact, &act); | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | 	  set_signal_hard_ignored (XSIG (i)); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #if defined (SIGPROF) && !defined (_MINIX)
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |       if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	sigaction (XSIG (i), &oact, (struct sigaction *)NULL); | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #endif /* SIGPROF && !_MINIX */
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /* !HAVE_POSIX_SIGNALS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; i < TERMSIGS_LENGTH; i++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |       /* If we've already trapped it, don't do anything. */ | 
					
						
							|  |  |  |       if (signal_is_trapped (XSIG (i))) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  |       XHANDLER(i) = signal (XSIG (i), termsig_sighandler); | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       XSAFLAGS(i) = 0; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       /* Don't do anything with signals that are ignored at shell entry
 | 
					
						
							|  |  |  | 	 if the shell is not interactive. */ | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |       /* XXX - should we do this for interactive shells, too? */ | 
					
						
							|  |  |  |       if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	  signal (XSIG (i), SIG_IGN); | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | 	  set_signal_hard_ignored (XSIG (i)); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #ifdef SIGPROF
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |       if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	signal (XSIG (i), XHANDLER (i)); | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* !HAVE_POSIX_SIGNALS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   termsigs_initialized = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | initialize_shell_signals () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (interactive) | 
					
						
							|  |  |  |     initialize_terminating_signals (); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							|  |  |  |   /* All shells use the signal mask they inherit, and pass it along
 | 
					
						
							|  |  |  |      to child processes.  Children will never block SIGCHLD, though. */ | 
					
						
							|  |  |  |   sigemptyset (&top_level_mask); | 
					
						
							|  |  |  |   sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &top_level_mask); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #  if defined (SIGCHLD)
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   sigdelset (&top_level_mask, SIGCHLD); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* And, some signals that are specifically ignored by the shell. */ | 
					
						
							|  |  |  |   set_signal_handler (SIGQUIT, SIG_IGN); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (interactive) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       set_signal_handler (SIGINT, sigint_sighandler); | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |       get_original_signal (SIGTERM); | 
					
						
							|  |  |  |       if (signal_is_hard_ignored (SIGTERM) == 0) | 
					
						
							|  |  |  | 	set_signal_handler (SIGTERM, sigterm_sighandler); | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       set_sigwinch_handler (); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | reset_terminating_signals () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  | #if defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							|  |  |  |   struct sigaction act; | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   if (termsigs_initialized == 0) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   act.sa_flags = 0; | 
					
						
							|  |  |  |   sigemptyset (&act.sa_mask); | 
					
						
							|  |  |  |   for (i = 0; i < TERMSIGS_LENGTH; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       /* Skip a signal if it's trapped or handled specially, because the
 | 
					
						
							|  |  |  | 	 trap code will restore the correct value. */ | 
					
						
							|  |  |  |       if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i))) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       act.sa_handler = XHANDLER (i); | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       act.sa_flags = XSAFLAGS (i); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       sigaction (XSIG (i), &act, (struct sigaction *) NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else /* !HAVE_POSIX_SIGNALS */
 | 
					
						
							|  |  |  |   for (i = 0; i < TERMSIGS_LENGTH; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i))) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       signal (XSIG (i), XHANDLER (i)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* !HAVE_POSIX_SIGNALS */
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   termsigs_initialized = 0; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #undef XSIG
 | 
					
						
							|  |  |  | #undef XHANDLER
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-18 13:15:12 +00:00
										 |  |  | /* Run some of the cleanups that should be performed when we run
 | 
					
						
							|  |  |  |    jump_to_top_level from a builtin command context.  XXX - might want to | 
					
						
							|  |  |  |    also call reset_parser here. */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | top_level_cleanup () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* Clean up string parser environment. */ | 
					
						
							|  |  |  |   while (parse_and_execute_level) | 
					
						
							|  |  |  |     parse_and_execute_cleanup (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (PROCESS_SUBSTITUTION)
 | 
					
						
							|  |  |  |   unlink_fifo_list (); | 
					
						
							|  |  |  | #endif /* PROCESS_SUBSTITUTION */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   run_unwind_protects (); | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   loop_level = continuing = breaking = funcnest = 0; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   executing_list = comsub_ignore_return = return_catch_flag = 0; | 
					
						
							| 
									
										
										
										
											2008-11-18 13:15:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* What to do when we've been interrupted, and it is safe to handle it. */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | throw_to_top_level () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int print_newline = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (interrupt_state) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |       if (last_command_exit_value < 128) | 
					
						
							|  |  |  | 	last_command_exit_value = 128 + SIGINT; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       print_newline = 1; | 
					
						
							|  |  |  |       DELINTERRUPT; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (interrupt_state) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   last_command_exit_signal = (last_command_exit_value > 128) ? | 
					
						
							|  |  |  | 				(last_command_exit_value - 128) : 0; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   last_command_exit_value |= 128; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Run any traps set on SIGINT. */ | 
					
						
							|  |  |  |   run_interrupt_trap (); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   /* Clean up string parser environment. */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   while (parse_and_execute_level) | 
					
						
							|  |  |  |     parse_and_execute_cleanup (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (JOB_CONTROL)
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   give_terminal_to (shell_pgrp, 0); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif /* JOB_CONTROL */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   /* This needs to stay because jobs.c:make_child() uses it without resetting
 | 
					
						
							|  |  |  |      the signal mask. */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   reset_parser (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (READLINE)
 | 
					
						
							|  |  |  |   if (interactive) | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |     bashline_reset (); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #endif /* READLINE */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (PROCESS_SUBSTITUTION)
 | 
					
						
							|  |  |  |   unlink_fifo_list (); | 
					
						
							|  |  |  | #endif /* PROCESS_SUBSTITUTION */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   run_unwind_protects (); | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   loop_level = continuing = breaking = funcnest = 0; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   executing_list = comsub_ignore_return = return_catch_flag = 0; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (interactive && print_newline) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       fflush (stdout); | 
					
						
							|  |  |  |       fprintf (stderr, "\n"); | 
					
						
							|  |  |  |       fflush (stderr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* An interrupted `wait' command in a script does not exit the script. */ | 
					
						
							|  |  |  |   if (interactive || (interactive_shell && !shell_initialized) || | 
					
						
							|  |  |  |       (print_newline && signal_is_trapped (SIGINT))) | 
					
						
							|  |  |  |     jump_to_top_level (DISCARD); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     jump_to_top_level (EXITPROG); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This is just here to isolate the longjmp calls. */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | jump_to_top_level (value) | 
					
						
							|  |  |  |      int value; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   longjmp (top_level, value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sighandler | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  | termsig_sighandler (sig) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |      int sig; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-21 20:49:12 -05:00
										 |  |  |   /* If we get called twice with the same signal before handling it,
 | 
					
						
							|  |  |  |      terminate right away. */ | 
					
						
							|  |  |  |   if ( | 
					
						
							|  |  |  | #ifdef SIGHUP
 | 
					
						
							|  |  |  |     sig != SIGHUP && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGINT
 | 
					
						
							|  |  |  |     sig != SIGINT && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGDANGER
 | 
					
						
							|  |  |  |     sig != SIGDANGER && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGPIPE
 | 
					
						
							|  |  |  |     sig != SIGPIPE && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGALRM
 | 
					
						
							|  |  |  |     sig != SIGALRM && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGTERM
 | 
					
						
							|  |  |  |     sig != SIGTERM && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGXCPU
 | 
					
						
							|  |  |  |     sig != SIGXCPU && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGXFSZ
 | 
					
						
							|  |  |  |     sig != SIGXFSZ && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGVTALRM
 | 
					
						
							|  |  |  |     sig != SIGVTALRM && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGLOST
 | 
					
						
							|  |  |  |     sig != SIGLOST && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGUSR1
 | 
					
						
							|  |  |  |     sig != SIGUSR1 && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGUSR2
 | 
					
						
							|  |  |  |    sig != SIGUSR2 && | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |    sig == terminating_signal) | 
					
						
							|  |  |  |     terminate_immediately = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  |   terminating_signal = sig; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   /* XXX - should this also trigger when interrupt_immediately is set? */ | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  |   if (terminate_immediately) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | #if defined (HISTORY)
 | 
					
						
							|  |  |  |       /* XXX - will inhibit history file being written */ | 
					
						
							| 
									
										
										
										
											2011-11-22 20:00:47 -05:00
										 |  |  | #  if defined (READLINE)
 | 
					
						
							|  |  |  |       if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0)) | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  |         history_lines_this_session = 0; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  |       terminate_immediately = 0; | 
					
						
							|  |  |  |       termsig_handler (sig); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | #if defined (READLINE)
 | 
					
						
							|  |  |  |   /* Set the event hook so readline will call it after the signal handlers
 | 
					
						
							|  |  |  |      finish executing, so if this interrupted character input we can get | 
					
						
							|  |  |  |      quick response. */ | 
					
						
							|  |  |  |   if (interactive_shell && interactive && no_line_editing == 0) | 
					
						
							|  |  |  |     bashline_set_event_hook (); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-10 14:15:34 +00:00
										 |  |  |   SIGRETURN (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | termsig_handler (sig) | 
					
						
							|  |  |  |      int sig; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static int handling_termsig = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Simple semaphore to keep this function from being executed multiple
 | 
					
						
							|  |  |  |      times.  Since we no longer are running as a signal handler, we don't | 
					
						
							|  |  |  |      block multiple occurrences of the terminating signals while running. */ | 
					
						
							|  |  |  |   if (handling_termsig) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   handling_termsig = 1; | 
					
						
							|  |  |  |   terminating_signal = 0;	/* keep macro from re-testing true. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |   /* I don't believe this condition ever tests true. */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (sig == SIGINT && signal_is_trapped (SIGINT)) | 
					
						
							|  |  |  |     run_interrupt_trap (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HISTORY)
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   /* If we don't do something like this, the history will not be saved when
 | 
					
						
							|  |  |  |      an interactive shell is running in a terminal window that gets closed | 
					
						
							|  |  |  |      with the `close' button.  We can't test for RL_STATE_READCMD because | 
					
						
							|  |  |  |      readline no longer handles SIGTERM synchronously.  */ | 
					
						
							|  |  |  |   if (interactive_shell && interactive && (sig == SIGHUP || sig == SIGTERM) && remember_on_history) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     maybe_save_shell_history (); | 
					
						
							|  |  |  | #endif /* HISTORY */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (JOB_CONTROL)
 | 
					
						
							| 
									
										
										
										
											2011-11-21 20:51:19 -05:00
										 |  |  |   if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)))) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     hangup_all_jobs (); | 
					
						
							|  |  |  |   end_job_control (); | 
					
						
							|  |  |  | #endif /* JOB_CONTROL */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (PROCESS_SUBSTITUTION)
 | 
					
						
							|  |  |  |   unlink_fifo_list (); | 
					
						
							|  |  |  | #endif /* PROCESS_SUBSTITUTION */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   /* Reset execution context */ | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   loop_level = continuing = breaking = funcnest = 0; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   executing_list = comsub_ignore_return = return_catch_flag = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   run_exit_trap ();	/* XXX - run exit trap possibly in signal context? */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   set_signal_handler (sig, SIG_DFL); | 
					
						
							|  |  |  |   kill (getpid (), sig); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* What we really do when SIGINT occurs. */ | 
					
						
							|  |  |  | sighandler | 
					
						
							|  |  |  | sigint_sighandler (sig) | 
					
						
							|  |  |  |      int sig; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined (MUST_REINSTALL_SIGHANDLERS)
 | 
					
						
							|  |  |  |   signal (sig, sigint_sighandler); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* interrupt_state needs to be set for the stack of interrupts to work
 | 
					
						
							|  |  |  |      right.  Should it be set unconditionally? */ | 
					
						
							|  |  |  |   if (interrupt_state == 0) | 
					
						
							|  |  |  |     ADDINTERRUPT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   /* We will get here in interactive shells with job control active; allow
 | 
					
						
							|  |  |  |      an interactive wait to be interrupted. */ | 
					
						
							|  |  |  |   if (this_shell_builtin && this_shell_builtin == wait_builtin) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       last_command_exit_value = 128 + sig; | 
					
						
							|  |  |  |       wait_signal_received = sig; | 
					
						
							|  |  |  |       SIGRETURN (0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (interrupt_immediately) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       interrupt_immediately = 0; | 
					
						
							| 
									
										
										
										
											2011-11-21 20:51:19 -05:00
										 |  |  |       last_command_exit_value = 128 + sig; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       throw_to_top_level (); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | #if defined (READLINE)
 | 
					
						
							|  |  |  |   /* Set the event hook so readline will call it after the signal handlers
 | 
					
						
							|  |  |  |      finish executing, so if this interrupted character input we can get | 
					
						
							|  |  |  |      quick response. */ | 
					
						
							|  |  |  |   else if (RL_ISSTATE (RL_STATE_SIGHANDLER)) | 
					
						
							|  |  |  |     bashline_set_event_hook (); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   SIGRETURN (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | #if defined (SIGWINCH)
 | 
					
						
							|  |  |  | sighandler | 
					
						
							|  |  |  | sigwinch_sighandler (sig) | 
					
						
							|  |  |  |      int sig; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined (MUST_REINSTALL_SIGHANDLERS)
 | 
					
						
							|  |  |  |   set_signal_handler (SIGWINCH, sigwinch_sighandler); | 
					
						
							|  |  |  | #endif /* MUST_REINSTALL_SIGHANDLERS */
 | 
					
						
							|  |  |  |   sigwinch_received = 1; | 
					
						
							|  |  |  |   SIGRETURN (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* SIGWINCH */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | set_sigwinch_handler () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined (SIGWINCH)
 | 
					
						
							|  |  |  |  old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | unset_sigwinch_handler () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined (SIGWINCH)
 | 
					
						
							|  |  |  |   set_signal_handler (SIGWINCH, old_winch); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | sighandler | 
					
						
							|  |  |  | sigterm_sighandler (sig) | 
					
						
							|  |  |  |      int sig; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   sigterm_received = 1;		/* XXX - counter? */ | 
					
						
							|  |  |  |   SIGRETURN (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* Signal functions used by the rest of the code. */ | 
					
						
							|  |  |  | #if !defined (HAVE_POSIX_SIGNALS)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */ | 
					
						
							|  |  |  | sigprocmask (operation, newset, oldset) | 
					
						
							|  |  |  |      int operation, *newset, *oldset; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int old, new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (newset) | 
					
						
							|  |  |  |     new = *newset; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     new = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (operation) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case SIG_BLOCK: | 
					
						
							|  |  |  |       old = sigblock (new); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SIG_SETMASK: | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |       old = sigsetmask (new); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       internal_error (_("sigprocmask: %d: invalid operation"), operation); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (oldset) | 
					
						
							|  |  |  |     *oldset = old; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (SA_INTERRUPT)
 | 
					
						
							|  |  |  | #  define SA_INTERRUPT 0
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (SA_RESTART)
 | 
					
						
							|  |  |  | #  define SA_RESTART 0
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SigHandler * | 
					
						
							|  |  |  | set_signal_handler (sig, handler) | 
					
						
							|  |  |  |      int sig; | 
					
						
							|  |  |  |      SigHandler *handler; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct sigaction act, oact; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   act.sa_handler = handler; | 
					
						
							|  |  |  |   act.sa_flags = 0; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* XXX - bash-4.2 */ | 
					
						
							|  |  |  |   /* We don't want a child death to interrupt interruptible system calls, even
 | 
					
						
							|  |  |  |      if we take the time to reap children */ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | #if defined (SIGCHLD)
 | 
					
						
							| 
									
										
										
										
											2011-11-21 20:57:16 -05:00
										 |  |  |   if (sig == SIGCHLD) | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |     act.sa_flags |= SA_RESTART;		/* XXX */ | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   /* If we're installing a SIGTERM handler for interactive shells, we want
 | 
					
						
							|  |  |  |      it to be as close to SIG_IGN as possible. */ | 
					
						
							|  |  |  |   if (sig == SIGTERM && handler == sigterm_sighandler) | 
					
						
							|  |  |  |     act.sa_flags |= SA_RESTART;		/* XXX */ | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   sigemptyset (&act.sa_mask); | 
					
						
							|  |  |  |   sigemptyset (&oact.sa_mask); | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   if (sigaction (sig, &act, &oact) == 0) | 
					
						
							|  |  |  |     return (oact.sa_handler); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return (SIG_DFL); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* HAVE_POSIX_SIGNALS */
 |