1 /* quit.h -- How to handle SIGINT gracefully. */ 2 3 /* Copyright (C) 1993-2013 Free Software Foundation, Inc. 4 5 This file is part of GNU Bash, the Bourne Again SHell. 6 7 Bash is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 Bash is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Bash. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #if !defined (_QUIT_H_) 22 #define _QUIT_H_ 23 24 #include "sig.h" /* for sig_atomic_t */ 25 26 /* Non-zero means SIGINT has already occurred. */ 27 extern volatile sig_atomic_t interrupt_state; 28 extern volatile sig_atomic_t terminating_signal; 29 30 /* Macro to call a great deal. SIGINT just sets the interrupt_state variable. 31 When it is safe, put QUIT in the code, and the "interrupt" will take 32 place. The same scheme is used for terminating signals (e.g., SIGHUP) 33 and the terminating_signal variable. That calls a function which will 34 end up exiting the shell. */ 35 #define QUIT \ 36 do { \ 37 if (terminating_signal) termsig_handler (terminating_signal); \ 38 if (interrupt_state) throw_to_top_level (); \ 39 } while (0) 40 41 #define CHECK_ALRM \ 42 do { \ 43 if (sigalrm_seen) \ 44 sh_longjmp (alrmbuf, 1); \ 45 } while (0) 46 47 #define SETINTERRUPT interrupt_state = 1 48 #define CLRINTERRUPT interrupt_state = 0 49 50 #define ADDINTERRUPT interrupt_state++ 51 #define DELINTERRUPT interrupt_state-- 52 53 #define ISINTERRUPT interrupt_state != 0 54 55 /* The same sort of thing, this time just for signals that would ordinarily 56 cause the shell to terminate. */ 57 58 #define CHECK_TERMSIG \ 59 do { \ 60 if (terminating_signal) termsig_handler (terminating_signal); \ 61 } while (0) 62 63 #define LASTSIG() \ 64 (terminating_signal ? terminating_signal : (interrupt_state ? SIGINT : 0)) 65 66 #define CHECK_WAIT_INTR \ 67 do { \ 68 if (wait_intr_flag && wait_signal_received && this_shell_builtin && (this_shell_builtin == wait_builtin)) \ 69 sh_longjmp (wait_intr_buf, 1); \ 70 } while (0) 71 72 #define RESET_SIGTERM \ 73 do { \ 74 sigterm_received = 0; \ 75 } while (0) 76 77 #define CHECK_SIGTERM \ 78 do { \ 79 if (sigterm_received) termsig_handler (SIGTERM); \ 80 } while (0) 81 #endif /* _QUIT_H_ */ 82