📄 sig.c
字号:
{ /* 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); act.sa_flags = XSAFLAGS (i); 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 */}#undef XSIG#undef XHANDLER/* 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. */voidtop_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 (); loop_level = continuing = breaking = funcnest = 0; executing_list = comsub_ignore_return = return_catch_flag = 0;}/* What to do when we've been interrupted, and it is safe to handle it. */voidthrow_to_top_level (){ int print_newline = 0; if (interrupt_state) { print_newline = 1; DELINTERRUPT; } if (interrupt_state) return; last_command_exit_signal = (last_command_exit_value > 128) ? (last_command_exit_value - 128) : 0; last_command_exit_value |= 128; /* Run any traps set on SIGINT. */ run_interrupt_trap (); /* Clean up string parser environment. */ while (parse_and_execute_level) parse_and_execute_cleanup ();#if defined (JOB_CONTROL) give_terminal_to (shell_pgrp, 0);#endif /* JOB_CONTROL */#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS) /* This should not be necessary on systems using sigsetjmp/siglongjmp. */ sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);#endif reset_parser ();#if defined (READLINE) if (interactive) bashline_reset ();#endif /* READLINE */#if defined (PROCESS_SUBSTITUTION) unlink_fifo_list ();#endif /* PROCESS_SUBSTITUTION */ run_unwind_protects (); loop_level = continuing = breaking = funcnest = 0; executing_list = comsub_ignore_return = return_catch_flag = 0; 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. */voidjump_to_top_level (value) int value;{ longjmp (top_level, value);}sighandlertermsig_sighandler (sig) int sig;{ /* 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; terminating_signal = 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); } SIGRETURN (0);}voidtermsig_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. */ /* I don't believe this condition ever tests true. */ if (sig == SIGINT && signal_is_trapped (SIGINT)) run_interrupt_trap ();#if defined (HISTORY) if (interactive_shell && sig != SIGABRT) maybe_save_shell_history ();#endif /* HISTORY */#if defined (JOB_CONTROL) if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)))) hangup_all_jobs (); end_job_control ();#endif /* JOB_CONTROL */#if defined (PROCESS_SUBSTITUTION) unlink_fifo_list ();#endif /* PROCESS_SUBSTITUTION */ /* Reset execution context */ 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);}/* What we really do when SIGINT occurs. */sighandlersigint_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; if (interrupt_immediately) { interrupt_immediately = 0; last_command_exit_value = 128 + sig; throw_to_top_level (); } SIGRETURN (0);}#if defined (SIGWINCH)sighandlersigwinch_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 */voidset_sigwinch_handler (){#if defined (SIGWINCH) old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler);#endif}voidunset_sigwinch_handler (){#if defined (SIGWINCH) set_signal_handler (SIGWINCH, old_winch);#endif}/* Signal functions used by the rest of the code. */#if !defined (HAVE_POSIX_SIGNALS)#if defined (JOB_CONTROL)/* 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: sigsetmask (new); break; default: internal_error (_("sigprocmask: %d: invalid operation"), operation); } if (oldset) *oldset = old;}#endif /* JOB_CONTROL */#else#if !defined (SA_INTERRUPT)# define SA_INTERRUPT 0#endif#if !defined (SA_RESTART)# define SA_RESTART 0#endifSigHandler *set_signal_handler (sig, handler) int sig; SigHandler *handler;{ struct sigaction act, oact; act.sa_handler = handler; act.sa_flags = 0; /* 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 */ if (sig == SIGCHLD) act.sa_flags |= SA_RESTART; /* XXX */ sigemptyset (&act.sa_mask); sigemptyset (&oact.sa_mask); sigaction (sig, &act, &oact); return (oact.sa_handler);}#endif /* HAVE_POSIX_SIGNALS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -