diff options
| author | Chet Ramey <chet.ramey@case.edu> | 2018-05-22 16:51:07 -0400 |
|---|---|---|
| committer | Chet Ramey <chet.ramey@case.edu> | 2018-05-22 16:51:07 -0400 |
| commit | 9a51695bed07d37086c352372ac69d0a30039a6b (patch) | |
| tree | 4d0f57cba0dd1ec7a75aae56e18cfe9997d0b7a7 /shell.c | |
| parent | 7de27456f6494f5f9c11ea1c19024d0024f31112 (diff) | |
| download | bash-5.0-alpha.tar.gz | |
bash-5.0-alpha releasebash-5.0-alpha
Diffstat (limited to 'shell.c')
| -rw-r--r-- | shell.c | 112 |
1 files changed, 81 insertions, 31 deletions
@@ -1,6 +1,6 @@ /* shell.c -- GNU's idea of the POSIX shell specification. */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -51,6 +51,7 @@ #define NEED_SH_SETLINEBUF_DECL /* used in externs.h */ #include "shell.h" +#include "parser.h" #include "flags.h" #include "trap.h" #include "mailcheck.h" @@ -60,6 +61,7 @@ #if defined (JOB_CONTROL) #include "jobs.h" #else +extern int running_in_background; extern int initialize_job_control __P((int)); extern int get_tty_state __P((void)); #endif /* JOB_CONTROL */ @@ -101,22 +103,12 @@ extern int errno; extern char **environ; /* used if no third argument to main() */ #endif -extern char *dist_version, *release_status; -extern int patch_level, build_version; -extern int shell_level; -extern int subshell_environment; -extern int running_in_background; -extern int last_command_exit_value; -extern int line_number; -extern int expand_aliases; -extern int array_needs_making; extern int gnu_error_format; -extern char *primary_prompt, *secondary_prompt; -extern char *this_command_name; /* Non-zero means that this shell has already been run; i.e. you should call shell_reinitialize () if you need to start afresh. */ int shell_initialized = 0; +int bash_argv_initialized = 0; COMMAND *global_command = (COMMAND *)NULL; @@ -232,6 +224,8 @@ int dump_po_strings; /* Dump strings in $"..." in po format */ int wordexp_only = 0; /* Do word expansion only */ int protected_mode = 0; /* No command substitution with --wordexp */ +int pretty_print_mode = 0; /* pretty-print a shell script */ + #if defined (STRICT_POSIX) int posixly_correct = 1; /* Non-zero means posix.2 superset. */ #else @@ -260,6 +254,7 @@ static const struct { { "noprofile", Int, &no_profile, (char **)0x0 }, { "norc", Int, &no_rc, (char **)0x0 }, { "posix", Int, &posixly_correct, (char **)0x0 }, + { "pretty-print", Int, &pretty_print_mode, (char **)0x0 }, #if defined (WORDEXP_OPTION) { "protected", Int, &protected_mode, (char **)0x0 }, #endif @@ -297,6 +292,7 @@ int want_pending_command; /* -c flag supplied */ /* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */ char *command_execution_string; /* argument to -c option */ +char *shell_script_filename; /* shell script */ int malloc_trace_at_exit = 0; @@ -433,7 +429,7 @@ main (argc, argv, env) arg_index = 1; if (arg_index > argc) arg_index = argc; - command_execution_string = (char *)NULL; + command_execution_string = shell_script_filename = (char *)NULL; want_pending_command = locally_skip_execution = read_from_stdin = 0; default_input = stdin; #if defined (BUFFERED_INPUT) @@ -584,7 +580,7 @@ main (argc, argv, env) */ if (interactive_shell) { - char *term, *emacs, *inside_emacs;; + char *term, *emacs, *inside_emacs; int emacs_term, in_emacs; term = get_string_value ("TERM"); @@ -673,6 +669,22 @@ main (argc, argv, env) restricted = 0; #endif + /* Set positional parameters before running startup files. top_level_arg_index + holds the index of the current argument before setting the positional + parameters, so any changes performed in the startup files won't affect + later option processing. */ + if (wordexp_only) + ; /* nothing yet */ + else if (command_execution_string) + arg_index = bind_args (argv, arg_index, argc, 0); /* $0 ... $n */ + else if (arg_index != argc && read_from_stdin == 0) + { + shell_script_filename = argv[arg_index++]; + arg_index = bind_args (argv, arg_index, argc, 1); /* $1 ... $n */ + } + else + arg_index = bind_args (argv, arg_index, argc, 1); /* $1 ... $n */ + /* The startup files are run with `set -e' temporarily disabled. */ if (locally_skip_execution == 0 && running_setuid == 0) { @@ -703,7 +715,7 @@ main (argc, argv, env) if (wordexp_only) { startup_state = 3; - last_command_exit_value = run_wordexp (argv[arg_index]); + last_command_exit_value = run_wordexp (argv[top_level_arg_index]); exit_shell (last_command_exit_value); } #endif @@ -713,7 +725,6 @@ main (argc, argv, env) if (command_execution_string) { - arg_index = bind_args (argv, arg_index, argc, 0); startup_state = 2; if (debugging_mode) @@ -731,11 +742,8 @@ main (argc, argv, env) /* Get possible input filename and set up default_buffered_input or default_input as appropriate. */ - if (arg_index != argc && read_from_stdin == 0) - { - open_shell_script (argv[arg_index]); - arg_index++; - } + if (shell_script_filename) + open_shell_script (shell_script_filename); else if (interactive == 0) { /* In this mode, bash is reading a script from stdin, which is a @@ -747,16 +755,13 @@ main (argc, argv, env) #endif /* !BUFFERED_INPUT */ read_from_stdin = 1; } - else if (arg_index == argc) + else if (top_level_arg_index == argc) /* arg index before startup files */ /* "If there are no operands and the -c option is not specified, the -s option shall be assumed." */ read_from_stdin = 1; set_bash_input (); - /* Bind remaining args to $1 ... $n */ - arg_index = bind_args (argv, arg_index, argc, 1); - if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0 && (reading_shell_script || interactive_shell == 0)) start_debugger (); @@ -788,6 +793,14 @@ main (argc, argv, env) shell_initialized = 1; + if (pretty_print_mode && interactive_shell) + { + internal_warning (_("pretty-printing mode ignored in interactive shells")); + pretty_print_mode = 0; + } + if (pretty_print_mode) + exit_shell (pretty_print_loop ()); + /* Read commands until exit condition. */ reader_loop (); exit_shell (last_command_exit_value); @@ -1236,6 +1249,10 @@ maybe_make_restricted (name) temp++; if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME))) { +#if defined (RBASH_STATIC_PATH_VALUE) + bind_variable ("PATH", RBASH_STATIC_PATH_VALUE, 0); + stupidly_hack_special_variables ("PATH"); /* clear hash table */ +#endif set_var_read_only ("PATH"); set_var_read_only ("SHELL"); set_var_read_only ("ENV"); @@ -1406,13 +1423,21 @@ bind_args (argv, arg_start, arg_end, start_index) int arg_start, arg_end, start_index; { register int i; - WORD_LIST *args; + WORD_LIST *args, *tl; + + for (i = arg_start, args = tl = (WORD_LIST *)NULL; i < arg_end; i++) + { + if (args == 0) + args = tl = make_word_list (make_word (argv[i]), args); + else + { + tl->next = make_word_list (make_word (argv[i]), (WORD_LIST *)NULL); + tl = tl->next; + } + } - for (i = arg_start, args = (WORD_LIST *)NULL; i < arg_end; i++) - args = make_word_list (make_word (argv[i]), args); if (args) { - args = REVERSE_LIST (args, WORD_LIST *); if (start_index == 0) /* bind to $0...$n for sh -c command */ { /* Posix.2 4.56.3 says that the first argument after sh -c command @@ -1421,12 +1446,23 @@ bind_args (argv, arg_start, arg_end, start_index) FREE (dollar_vars[0]); dollar_vars[0] = savestring (args->word->word); remember_args (args->next, 1); - push_args (args->next); /* BASH_ARGV and BASH_ARGC */ + if (debugging_mode) + { + push_args (args->next); /* BASH_ARGV and BASH_ARGC */ + bash_argv_initialized = 1; + } } else /* bind to $1...$n for shell script */ { remember_args (args, 1); - push_args (args); /* BASH_ARGV and BASH_ARGC */ + /* We do this unconditionally so something like -O extdebug doesn't + do it first. We're setting the definitive positional params + here. */ + if (debugging_mode) + { + push_args (args); /* BASH_ARGV and BASH_ARGC */ + bash_argv_initialized = 1; + } } dispose_words (args); @@ -1504,6 +1540,9 @@ open_shell_script (script_name) { e = errno; file_error (filename); +#if defined (JOB_CONTROL) + end_job_control (); /* just in case we were run as bash -i script */ +#endif sh_exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT); } @@ -1523,6 +1562,9 @@ open_shell_script (script_name) errno = EINVAL; #endif file_error (filename); +#if defined (JOB_CONTROL) + end_job_control (); /* just in case we were run as bash -i script */ +#endif sh_exit (EX_NOINPUT); } @@ -1571,11 +1613,17 @@ open_shell_script (script_name) errno = e; file_error (filename); } +#if defined (JOB_CONTROL) + end_job_control (); /* just in case we were run as bash -i script */ +#endif exit (EX_NOEXEC); } else if (sample_len > 0 && (check_binary_file (sample, sample_len))) { internal_error (_("%s: cannot execute binary file"), filename); +#if defined (JOB_CONTROL) + end_job_control (); /* just in case we were run as bash -i script */ +#endif exit (EX_BINARY_FILE); } /* Now rewind the file back to the beginning. */ @@ -1722,6 +1770,7 @@ init_interactive () interactive = 1; #if defined (HISTORY) remember_on_history = enable_history_list = 1; /* XXX */ + histexp_flag = history_expansion; /* XXX */ #endif } @@ -1889,6 +1938,7 @@ shell_reinitialize () forced_interactive = interactive_shell = 0; subshell_environment = running_in_background = 0; expand_aliases = 0; + bash_argv_initialized = 0; /* XXX - should we set jobs_m_flag to 0 here? */ |
