| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 1 | This file is trap.def, from which is created trap.c. |
| 2 | It implements the builtin "trap" in Bash. |
| 3 | |
| 4 | Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. |
| 5 | |
| 6 | This file is part of GNU Bash, the Bourne Again SHell. |
| 7 | |
| 8 | Bash is free software; you can redistribute it and/or modify it under |
| 9 | the terms of the GNU General Public License as published by the Free |
| 10 | Software Foundation; either version 1, or (at your option) any later |
| 11 | version. |
| 12 | |
| 13 | Bash is distributed in the hope that it will be useful, but WITHOUT ANY |
| 14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 16 | for more details. |
| 17 | |
| 18 | You should have received a copy of the GNU General Public License along |
| 19 | with Bash; see the file COPYING. If not, write to the Free Software |
| 20 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
| 21 | |
| 22 | $PRODUCES trap.c |
| 23 | |
| 24 | $BUILTIN trap |
| 25 | $FUNCTION trap_builtin |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 26 | $SHORT_DOC trap [arg] [signal_spec] or trap -l |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 27 | The command ARG is to be read and executed when the shell receives |
| 28 | signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 29 | reset to their original values. If ARG is the null string each |
| 30 | SIGNAL_SPEC is ignored by the shell and by the commands it invokes. |
| 31 | If SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from |
| 32 | the shell. If SIGNAL_SPEC is DEBUG, ARG is executed after every |
| 33 | command. If ARG is `-p' then the trap commands associated with |
| 34 | each SIGNAL_SPEC are displayed. If no arguments are supplied or if |
| 35 | only `-p' is given, trap prints the list of commands associated with |
| 36 | each signal number. SIGNAL_SPEC is either a signal name in <signal.h> |
| 37 | or a signal number. `trap -l' prints a list of signal names and their |
| 38 | corresponding numbers. Note that a signal can be sent to the shell |
| 39 | with "kill -signal $$". |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 40 | $END |
| 41 | |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 42 | #include <config.h> |
| 43 | |
| 44 | #if defined (HAVE_UNISTD_H) |
| 45 | # include <unistd.h> |
| 46 | #endif |
| 47 | |
| 48 | #include "../bashtypes.h" |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 49 | #include <signal.h> |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 50 | #include <stdio.h> |
| 51 | #include "../bashansi.h" |
| 52 | |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 53 | #include "../shell.h" |
| 54 | #include "../trap.h" |
| 55 | #include "common.h" |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 56 | #include "bashgetopt.h" |
| 57 | |
| 58 | static int display_traps (); |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 59 | |
| 60 | /* The trap command: |
| 61 | |
| 62 | trap <arg> <signal ...> |
| 63 | trap <signal ...> |
| 64 | trap -l |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 65 | trap -p [sigspec ...] |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 66 | trap [--] |
| 67 | |
| 68 | Set things up so that ARG is executed when SIGNAL(s) N is recieved. |
| 69 | If ARG is the empty string, then ignore the SIGNAL(s). If there is |
| 70 | no ARG, then set the trap for SIGNAL(s) to its original value. Just |
| 71 | plain "trap" means to print out the list of commands associated with |
| 72 | each signal number. Single arg of "-l" means list the signal names. */ |
| 73 | |
| 74 | /* Possible operations to perform on the list of signals.*/ |
| 75 | #define SET 0 /* Set this signal to first_arg. */ |
| 76 | #define REVERT 1 /* Revert to this signals original value. */ |
| 77 | #define IGNORE 2 /* Ignore this signal. */ |
| 78 | |
| 79 | extern int interactive; |
| 80 | |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 81 | int |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 82 | trap_builtin (list) |
| 83 | WORD_LIST *list; |
| 84 | { |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 85 | int list_signal_names, display, result, opt; |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 86 | |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 87 | list_signal_names = display = 0; |
| 88 | result = EXECUTION_SUCCESS; |
| 89 | reset_internal_getopt (); |
| 90 | while ((opt = internal_getopt (list, "lp")) != -1) |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 91 | { |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 92 | switch (opt) |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 93 | { |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 94 | case 'l': |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 95 | list_signal_names++; |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 96 | break; |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 97 | case 'p': |
| 98 | display++; |
| 99 | break; |
| 100 | default: |
| 101 | builtin_usage (); |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 102 | return (EX_USAGE); |
| 103 | } |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 104 | } |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 105 | list = loptend; |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 106 | |
| 107 | if (list_signal_names) |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 108 | return (display_signal_list ((WORD_LIST *)NULL, 1)); |
| 109 | else if (display || list == 0) |
| 110 | return (display_traps (list)); |
| 111 | else |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 112 | { |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 113 | char *first_arg; |
| 114 | int operation, sig; |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 115 | |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 116 | operation = SET; |
| 117 | first_arg = list->word->word; |
| 118 | if (first_arg && *first_arg && signal_object_p (first_arg)) |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 119 | operation = REVERT; |
| 120 | else |
| 121 | { |
| 122 | list = list->next; |
| 123 | if (*first_arg == '\0') |
| 124 | operation = IGNORE; |
| 125 | else if (first_arg[0] == '-' && !first_arg[1]) |
| 126 | operation = REVERT; |
| 127 | } |
| 128 | |
| 129 | while (list) |
| 130 | { |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 131 | sig = decode_signal (list->word->word); |
| 132 | |
| 133 | if (sig == NO_SIG) |
| 134 | { |
| 135 | builtin_error ("%s: not a signal specification", |
| 136 | list->word->word); |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 137 | result = EXECUTION_FAILURE; |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 138 | } |
| 139 | else |
| 140 | { |
| 141 | switch (operation) |
| 142 | { |
| 143 | case SET: |
| 144 | set_signal (sig, first_arg); |
| 145 | break; |
| 146 | |
| 147 | case REVERT: |
| 148 | restore_default_signal (sig); |
| 149 | |
| 150 | /* Signals that the shell treats specially need special |
| 151 | handling. */ |
| 152 | switch (sig) |
| 153 | { |
| 154 | case SIGINT: |
| 155 | if (interactive) |
| 156 | set_signal_handler (SIGINT, sigint_sighandler); |
| 157 | else |
| 158 | set_signal_handler (SIGINT, termination_unwind_protect); |
| 159 | break; |
| 160 | |
| 161 | case SIGQUIT: |
| 162 | /* Always ignore SIGQUIT. */ |
| 163 | set_signal_handler (SIGQUIT, SIG_IGN); |
| 164 | break; |
| 165 | case SIGTERM: |
| 166 | #if defined (JOB_CONTROL) |
| 167 | case SIGTTIN: |
| 168 | case SIGTTOU: |
| 169 | case SIGTSTP: |
| 170 | #endif /* JOB_CONTROL */ |
| 171 | if (interactive) |
| 172 | set_signal_handler (sig, SIG_IGN); |
| 173 | break; |
| 174 | } |
| 175 | break; |
| 176 | |
| 177 | case IGNORE: |
| 178 | ignore_signal (sig); |
| 179 | break; |
| 180 | } |
| 181 | } |
| 182 | list = list->next; |
| 183 | } |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 184 | } |
| 185 | |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 186 | return (result); |
| 187 | } |
| 188 | |
| 189 | static void |
| 190 | showtrap (i) |
| 191 | int i; |
| 192 | { |
| 193 | char *t, *p; |
| 194 | |
| 195 | p = trap_list[i]; |
| 196 | |
| 197 | if (p == (char *)DEFAULT_SIG) |
| 198 | return; |
| 199 | |
| 200 | t = (p == (char *)IGNORE_SIG) ? (char *)NULL : single_quote (p); |
| 201 | printf ("trap -- %s %s\n", t ? t : "''", signal_name (i)); |
| 202 | if (t) |
| 203 | free (t); |
| 204 | } |
| 205 | |
| 206 | static int |
| 207 | display_traps (list) |
| 208 | WORD_LIST *list; |
| 209 | { |
| 210 | int result, i; |
| 211 | |
| 212 | if (list == 0) |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 213 | { |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 214 | for (i = 0; i <= NSIG; i++) |
| 215 | showtrap (i); |
| 216 | return (EXECUTION_SUCCESS); |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 217 | } |
| Jari Aalto | ccc6cda | 1996-12-23 17:02:34 +0000 | [diff] [blame^] | 218 | |
| 219 | for (result = EXECUTION_SUCCESS; list; list = list->next) |
| 220 | { |
| 221 | i = decode_signal (list->word->word); |
| 222 | if (i == NO_SIG) |
| 223 | { |
| 224 | result = EXECUTION_FAILURE; |
| 225 | builtin_error ("%s: not a signal specification", list->word->word); |
| 226 | } |
| 227 | else |
| 228 | showtrap (i); |
| 229 | } |
| 230 | |
| 231 | return (result); |
| Jari Aalto | 726f638 | 1996-08-26 18:22:31 +0000 | [diff] [blame] | 232 | } |