diff options
Diffstat (limited to 'builtins/trap.def')
-rw-r--r-- | builtins/trap.def | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/builtins/trap.def b/builtins/trap.def new file mode 100644 index 0000000..b81651d --- /dev/null +++ b/builtins/trap.def @@ -0,0 +1,204 @@ +This file is trap.def, from which is created trap.c. +It implements the builtin "trap" in Bash. + +Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. + +This file is part of GNU Bash, the Bourne Again SHell. + +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 1, or (at your option) any later +version. + +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. + +You should have received a copy of the GNU General Public License along +with Bash; see the file COPYING. If not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +$PRODUCES trap.c + +$BUILTIN trap +$FUNCTION trap_builtin +$SHORT_DOC trap [arg] [signal_spec] +The command ARG is to be read and executed when the shell receives +signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are +reset to their original values. If ARG is the null string this +signal is ignored by the shell and by the commands it invokes. If +SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from +the shell. The trap command with no arguments prints the list of +commands associated with each signal number. SIGNAL_SPEC is either +a signal name in <signal.h>, or a signal number. The syntax `trap -l' +prints a list of signal names and their corresponding numbers. +Note that a signal can be sent to the shell with "kill -signal $$". +$END + +#include <sys/types.h> +#include <signal.h> +#include "../shell.h" +#include "../trap.h" +#include "common.h" + +/* The trap command: + + trap <arg> <signal ...> + trap <signal ...> + trap -l + trap [--] + + Set things up so that ARG is executed when SIGNAL(s) N is recieved. + If ARG is the empty string, then ignore the SIGNAL(s). If there is + no ARG, then set the trap for SIGNAL(s) to its original value. Just + plain "trap" means to print out the list of commands associated with + each signal number. Single arg of "-l" means list the signal names. */ + +/* Possible operations to perform on the list of signals.*/ +#define SET 0 /* Set this signal to first_arg. */ +#define REVERT 1 /* Revert to this signals original value. */ +#define IGNORE 2 /* Ignore this signal. */ + +extern int interactive; + +trap_builtin (list) + WORD_LIST *list; +{ + register int i; + int list_signal_names = 0; + + while (list) + { + if (ISOPTION (list->word->word, 'l')) + { + list_signal_names++; + list = list->next; + } + else if (ISOPTION (list->word->word, '-')) + { + list = list->next; + break; + } + else if ((*list->word->word == '-') && list->word->word[1]) + { + bad_option (list->word->word); + builtin_error ("usage: trap [-l] [arg] [sigspec]"); + return (EX_USAGE); + } + else + break; + } + + if (list_signal_names) + { + int column = 0; + + for (i = 0; i < NSIG; i++) + { + printf ("%2d) %s", i, signal_name (i)); + if (++column < 4) + printf ("\t"); + else + { + printf ("\n"); + column = 0; + } + } + if (column != 0) + printf ("\n"); + return (EXECUTION_SUCCESS); + } + + if (list) + { + char *first_arg = list->word->word; + int operation = SET, any_failed = 0; + + if (signal_object_p (first_arg)) + operation = REVERT; + else + { + list = list->next; + if (*first_arg == '\0') + operation = IGNORE; + else if (first_arg[0] == '-' && !first_arg[1]) + operation = REVERT; + } + + while (list) + { + int sig; + + sig = decode_signal (list->word->word); + + if (sig == NO_SIG) + { + builtin_error ("%s: not a signal specification", + list->word->word); + any_failed++; + } + else + { + switch (operation) + { + case SET: + set_signal (sig, first_arg); + break; + + case REVERT: + restore_default_signal (sig); + + /* Signals that the shell treats specially need special + handling. */ + switch (sig) + { + case SIGINT: + if (interactive) + set_signal_handler (SIGINT, sigint_sighandler); + else + set_signal_handler (SIGINT, termination_unwind_protect); + break; + + case SIGQUIT: + /* Always ignore SIGQUIT. */ + set_signal_handler (SIGQUIT, SIG_IGN); + break; + case SIGTERM: +#if defined (JOB_CONTROL) + case SIGTTIN: + case SIGTTOU: + case SIGTSTP: +#endif /* JOB_CONTROL */ + if (interactive) + set_signal_handler (sig, SIG_IGN); + break; + } + break; + + case IGNORE: + ignore_signal (sig); + break; + } + } + list = list->next; + } + return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE); + } + + for (i = 0; i < NSIG; i++) + { + char *t, *p; + + p = trap_list[i]; + + if (p == (char *)DEFAULT_SIG) + continue; + + t = (p == (char *)IGNORE_SIG) ? (char *)NULL : single_quote (p); + printf ("trap -- %s %s\n", t ? t : "''", signal_name (i)); + if (t) + free (t); + } + return (EXECUTION_SUCCESS); +} |