X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Fbash.git;a=blobdiff_plain;f=flags.c;h=eaec9aae86d0e2f0d15fef6e5f0e8ef8d821b342;hp=02b466c0ad1e94e76e7f6c46e7f3713d06bf4d2c;hb=HEAD;hpb=e8ce775db824de329b81293b4e5d8fbd65624528 diff --git a/flags.c b/flags.c index 02b466c..eaec9aa 100644 --- a/flags.c +++ b/flags.c @@ -1,25 +1,24 @@ /* flags.c -- Everything about flags except the `set' command. That is in builtins.c */ -/* Copyright (C) 1987,1989 Free Software Foundation, Inc. +/* Copyright (C) 1987-2009 Free Software Foundation, Inc. -This file is part of GNU Bash, the Bourne Again SHell. + 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 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. -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. + 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. */ + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ -/* Flags hacking. */ #include "config.h" #if defined (HAVE_UNISTD_H) # include @@ -28,17 +27,27 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "shell.h" #include "flags.h" +#if defined (BANG_HISTORY) +# include "bashhist.h" +#endif + #if defined (JOB_CONTROL) -extern int set_job_control (); +extern int set_job_control __P((int)); #endif #if defined (RESTRICTED_SHELL) extern char *shell_name; #endif +extern int shell_initialized; +extern int builtin_ignoring_errexit; + +/* -c, -s invocation options -- not really flags, but they show up in $- */ +extern int want_pending_command, read_from_stdin; + /* **************************************************************** */ /* */ -/* The Standard Sh Flags. */ +/* The Standard sh Flags. */ /* */ /* **************************************************************** */ @@ -51,7 +60,9 @@ int mark_modified_vars = 0; int asynchronous_notification = 0; /* Non-zero means exit immediately if a command exits with a non-zero - exit status. */ + exit status. The first is what controls set -e; the second is what + bash uses internally. */ +int errexit_flag = 0; int exit_immediately_on_error = 0; /* Non-zero means disable filename globbing. */ @@ -64,7 +75,7 @@ int place_keywords_in_env = 0; /* Non-zero means read commands, but don't execute them. This is useful for debugging shell scripts that should do something hairy and possibly - desctructive. */ + destructive. */ int read_but_dont_execute = 0; /* Non-zero means end of file is after one command. */ @@ -118,7 +129,11 @@ int hashing_enabled = 1; #if defined (BANG_HISTORY) /* Non-zero means that we are doing history expansion. The default. This means !22 gets the 22nd line of history. */ +# if defined (STRICT_POSIX) +int history_expansion = 0; +# else int history_expansion = 1; +# endif #endif /* BANG_HISTORY */ /* Non-zero means that we allow comments to appear in interactive commands. */ @@ -129,7 +144,8 @@ int interactive_comments = 1; disallows: changing directories, command or path names containing `/', unsetting or resetting the values of $PATH and $SHELL, and any type of output redirection. */ -int restricted = 0; +int restricted = 0; /* currently restricted */ +int restricted_shell = 0; /* shell was started in restricted mode. */ #endif /* RESTRICTED_SHELL */ /* Non-zero means that this shell is running in `privileged' mode. This @@ -143,19 +159,30 @@ int privileged_mode = 0; int brace_expansion = 1; #endif +/* Non-zero means that shell functions inherit the DEBUG trap. */ +int function_trace_mode = 0; + +/* Non-zero means that shell functions inherit the ERR trap. */ +int error_trace_mode = 0; + +/* Non-zero means that the rightmost non-zero exit status in a pipeline + is the exit status of the entire pipeline. If each processes exits + with a 0 status, the status of the pipeline is 0. */ +int pipefail_opt = 0; + /* **************************************************************** */ /* */ /* The Flags ALIST. */ /* */ /* **************************************************************** */ -struct flags_alist shell_flags[] = { +const struct flags_alist shell_flags[] = { /* Standard sh flags. */ { 'a', &mark_modified_vars }, #if defined (JOB_CONTROL) { 'b', &asynchronous_notification }, #endif /* JOB_CONTROL */ - { 'e', &exit_immediately_on_error }, + { 'e', &errexit_flag }, { 'f', &disallow_filename_globbing }, { 'h', &hashing_enabled }, { 'i', &forced_interactive }, @@ -172,29 +199,29 @@ struct flags_alist shell_flags[] = { { 'u', &unbound_vars_is_error }, { 'v', &echo_input_at_read }, { 'x', &echo_command_at_execute }, - { 'C', &noclobber }, /* New flags that control non-standard things. */ #if 0 { 'l', &lexical_scoping }, #endif - { 'I', &no_invisible_vars }, - - { 'P', &no_symbolic_links }, - #if defined (BRACE_EXPANSION) { 'B', &brace_expansion }, #endif - + { 'C', &noclobber }, + { 'E', &error_trace_mode }, #if defined (BANG_HISTORY) { 'H', &history_expansion }, #endif /* BANG_HISTORY */ - + { 'I', &no_invisible_vars }, + { 'P', &no_symbolic_links }, + { 'T', &function_trace_mode }, {0, (int *)NULL} }; #define NUM_SHELL_FLAGS (sizeof (shell_flags) / sizeof (struct flags_alist)) +char optflags[NUM_SHELL_FLAGS+4] = { '+' }; + int * find_flag (name) int name; @@ -209,8 +236,8 @@ find_flag (name) } /* Change the state of a flag, and return it's original value, or return - FLAG_ERROR if there is no flag called NAME. ON_OR_OFF should be one - of FLAG_ON or FLAG_OFF. */ + FLAG_ERROR if there is no flag FLAG. ON_OR_OFF must be either + FLAG_ON or FLAG_OFF. */ int change_flag (flag, on_or_off) int flag; @@ -218,54 +245,58 @@ change_flag (flag, on_or_off) { int *value, old_value; - value = find_flag (flag); - #if defined (RESTRICTED_SHELL) /* Don't allow "set +r" in a shell which is `restricted'. */ if (restricted && flag == 'r' && on_or_off == FLAG_OFF) return (FLAG_ERROR); #endif /* RESTRICTED_SHELL */ - if (value == (int *)FLAG_UNKNOWN) + value = find_flag (flag); + + if ((value == (int *)FLAG_UNKNOWN) || (on_or_off != FLAG_ON && on_or_off != FLAG_OFF)) return (FLAG_ERROR); old_value = *value; - - if (on_or_off == FLAG_ON) - *value = 1; - else if (on_or_off == FLAG_OFF) - *value = 0; - else - return (FLAG_ERROR); + *value = (on_or_off == FLAG_ON) ? 1 : 0; /* Special cases for a few flags. */ switch (flag) { +#if defined (BANG_HISTORY) + case 'H': + if (on_or_off == FLAG_ON) + bash_initialize_history (); + break; +#endif + #if defined (JOB_CONTROL) case 'm': set_job_control (on_or_off == FLAG_ON); break; #endif /* JOB_CONTROL */ -#if defined (RESTRICTED_SHELL) - case 'r': - if (on_or_off == FLAG_ON) - maybe_make_restricted (shell_name); + case 'e': + if (builtin_ignoring_errexit == 0) + exit_immediately_on_error = errexit_flag; break; -#endif -#if defined (BANG_HISTORY) - case 'H': - if (on_or_off == FLAG_ON) - bash_initialize_history (); + case 'n': + if (interactive_shell) + read_but_dont_execute = 0; break; -#endif case 'p': if (on_or_off == FLAG_OFF) disable_priv_mode (); + break; +#if defined (RESTRICTED_SHELL) + case 'r': + if (on_or_off == FLAG_ON && shell_initialized) + maybe_make_restricted (shell_name); break; +#endif + } return (old_value); @@ -279,11 +310,16 @@ which_set_flags () char *temp; int i, string_index; - temp = xmalloc (1 + NUM_SHELL_FLAGS); + temp = (char *)xmalloc (1 + NUM_SHELL_FLAGS + read_from_stdin + want_pending_command); for (i = string_index = 0; shell_flags[i].name; i++) if (*(shell_flags[i].value)) temp[string_index++] = shell_flags[i].name; + if (want_pending_command) + temp[string_index++] = 'c'; + if (read_from_stdin) + temp[string_index++] = 's'; + temp[string_index] = '\0'; return (temp); } @@ -295,7 +331,7 @@ reset_shell_flags () place_keywords_in_env = read_but_dont_execute = just_one_command = 0; noclobber = unbound_vars_is_error = echo_input_at_read = 0; echo_command_at_execute = jobs_m_flag = forced_interactive = 0; - no_symbolic_links = no_invisible_vars = privileged_mode = 0; + no_symbolic_links = no_invisible_vars = privileged_mode = pipefail_opt = 0; hashing_enabled = interactive_comments = 1; @@ -315,3 +351,15 @@ reset_shell_flags () restricted = 0; #endif } + +void +initialize_flags () +{ + register int i; + + for (i = 0; shell_flags[i].name; i++) + optflags[i+1] = shell_flags[i].name; + optflags[++i] = 'o'; + optflags[++i] = ';'; + optflags[i+1] = '\0'; +}