LCOV - code coverage report
Current view: top level - bash-4.4.23 - shell.c (source / functions) Hit Total Coverage
Test: cov-bash.info Lines: 300 645 46.5 %
Date: 2020-10-29 14:49:28 Functions: 19 27 70.4 %

          Line data    Source code
       1             : /* shell.c -- GNU's idea of the POSIX shell specification. */
       2             : 
       3             : /* Copyright (C) 1987-2015 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             : /*
      22             :   Birthdate:
      23             :   Sunday, January 10th, 1988.
      24             :   Initial author: Brian Fox
      25             : */
      26             : #define INSTALL_DEBUG_MODE
      27             : 
      28             : #include "config.h"
      29             : 
      30             : #include "bashtypes.h"
      31             : #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
      32             : #  include <sys/file.h>
      33             : #endif
      34             : #include "posixstat.h"
      35             : #include "posixtime.h"
      36             : #include "bashansi.h"
      37             : #include <stdio.h>
      38             : #include <signal.h>
      39             : #include <errno.h>
      40             : #include "filecntl.h"
      41             : #if defined (HAVE_PWD_H)
      42             : #  include <pwd.h>
      43             : #endif
      44             : 
      45             : #if defined (HAVE_UNISTD_H)
      46             : #  include <unistd.h>
      47             : #endif
      48             : 
      49             : #include "bashintl.h"
      50             : 
      51             : #define NEED_SH_SETLINEBUF_DECL         /* used in externs.h */
      52             : 
      53             : #include "shell.h"
      54             : #include "flags.h"
      55             : #include "trap.h"
      56             : #include "mailcheck.h"
      57             : #include "builtins.h"
      58             : #include "builtins/common.h"
      59             : 
      60             : #if defined (JOB_CONTROL)
      61             : #include "jobs.h"
      62             : #else
      63             : extern int initialize_job_control __P((int));
      64             : extern int get_tty_state __P((void));
      65             : #endif /* JOB_CONTROL */
      66             : 
      67             : #include "input.h"
      68             : #include "execute_cmd.h"
      69             : #include "findcmd.h"
      70             : 
      71             : #if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
      72             : #  include <malloc/shmalloc.h>
      73             : #endif
      74             : 
      75             : #if defined (HISTORY)
      76             : #  include "bashhist.h"
      77             : #  include <readline/history.h>
      78             : #endif
      79             : 
      80             : #if defined (READLINE)
      81             : #  include <readline/readline.h>
      82             : #  include "bashline.h"
      83             : #endif
      84             : 
      85             : #include <tilde/tilde.h>
      86             : #include <glob/strmatch.h>
      87             : 
      88             : #if defined (__OPENNT)
      89             : #  include <opennt/opennt.h>
      90             : #endif
      91             : 
      92             : #if !defined (HAVE_GETPW_DECLS)
      93             : extern struct passwd *getpwuid ();
      94             : #endif /* !HAVE_GETPW_DECLS */
      95             : 
      96             : #if !defined (errno)
      97             : extern int errno;
      98             : #endif
      99             : 
     100             : #if defined (NO_MAIN_ENV_ARG)
     101             : extern char **environ;  /* used if no third argument to main() */
     102             : #endif
     103             : 
     104             : extern char *dist_version, *release_status;
     105             : extern int patch_level, build_version;
     106             : extern int shell_level;
     107             : extern int subshell_environment;
     108             : extern int running_in_background;
     109             : extern int last_command_exit_value;
     110             : extern int line_number;
     111             : extern int expand_aliases;
     112             : extern int array_needs_making;
     113             : extern int gnu_error_format;
     114             : extern char *primary_prompt, *secondary_prompt;
     115             : extern char *this_command_name;
     116             : 
     117             : /* Non-zero means that this shell has already been run; i.e. you should
     118             :    call shell_reinitialize () if you need to start afresh. */
     119             : int shell_initialized = 0;
     120             : 
     121             : COMMAND *global_command = (COMMAND *)NULL;
     122             : 
     123             : /* Information about the current user. */
     124             : struct user_info current_user =
     125             : {
     126             :   (uid_t)-1, (uid_t)-1, (gid_t)-1, (gid_t)-1,
     127             :   (char *)NULL, (char *)NULL, (char *)NULL
     128             : };
     129             : 
     130             : /* The current host's name. */
     131             : char *current_host_name = (char *)NULL;
     132             : 
     133             : /* Non-zero means that this shell is a login shell.
     134             :    Specifically:
     135             :    0 = not login shell.
     136             :    1 = login shell from getty (or equivalent fake out)
     137             :   -1 = login shell from "--login" (or -l) flag.
     138             :   -2 = both from getty, and from flag.
     139             :  */
     140             : int login_shell = 0;
     141             : 
     142             : /* Non-zero means that at this moment, the shell is interactive.  In
     143             :    general, this means that the shell is at this moment reading input
     144             :    from the keyboard. */
     145             : int interactive = 0;
     146             : 
     147             : /* Non-zero means that the shell was started as an interactive shell. */
     148             : int interactive_shell = 0;
     149             : 
     150             : /* Non-zero means to send a SIGHUP to all jobs when an interactive login
     151             :    shell exits. */
     152             : int hup_on_exit = 0;
     153             : 
     154             : /* Non-zero means to list status of running and stopped jobs at shell exit */
     155             : int check_jobs_at_exit = 0;
     156             : 
     157             : /* Non-zero means to change to a directory name supplied as a command name */
     158             : int autocd = 0;
     159             : 
     160             : /* Tells what state the shell was in when it started:
     161             :         0 = non-interactive shell script
     162             :         1 = interactive
     163             :         2 = -c command
     164             :         3 = wordexp evaluation
     165             :    This is a superset of the information provided by interactive_shell.
     166             : */
     167             : int startup_state = 0;
     168             : int reading_shell_script = 0;
     169             : 
     170             : /* Special debugging helper. */
     171             : int debugging_login_shell = 0;
     172             : 
     173             : /* The environment that the shell passes to other commands. */
     174             : char **shell_environment;
     175             : 
     176             : /* Non-zero when we are executing a top-level command. */
     177             : int executing = 0;
     178             : 
     179             : /* The number of commands executed so far. */
     180             : int current_command_number = 1;
     181             : 
     182             : /* Non-zero is the recursion depth for commands. */
     183             : int indirection_level = 0;
     184             : 
     185             : /* The name of this shell, as taken from argv[0]. */
     186             : char *shell_name = (char *)NULL;
     187             : 
     188             : /* time in seconds when the shell was started */
     189             : time_t shell_start_time;
     190             : 
     191             : /* Are we running in an emacs shell window? */
     192             : int running_under_emacs;
     193             : 
     194             : /* Do we have /dev/fd? */
     195             : #ifdef HAVE_DEV_FD
     196             : int have_devfd = HAVE_DEV_FD;
     197             : #else
     198             : int have_devfd = 0;
     199             : #endif
     200             : 
     201             : /* The name of the .(shell)rc file. */
     202             : static char *bashrc_file = DEFAULT_BASHRC;
     203             : 
     204             : /* Non-zero if we are finding the scripts requirements. */
     205             : int rpm_requires;
     206             : 
     207             : /* Non-zero means to act more like the Bourne shell on startup. */
     208             : static int act_like_sh;
     209             : 
     210             : /* Non-zero if this shell is being run by `su'. */
     211             : static int su_shell;
     212             : 
     213             : /* Non-zero if we have already expanded and sourced $ENV. */
     214             : static int sourced_env;
     215             : 
     216             : /* Is this shell running setuid? */
     217             : static int running_setuid;
     218             : 
     219             : /* Values for the long-winded argument names. */
     220             : static int debugging;                   /* Do debugging things. */
     221             : static int no_rc;                       /* Don't execute ~/.bashrc */
     222             : static int no_profile;                  /* Don't execute .profile */
     223             : static int do_version;                  /* Display interesting version info. */
     224             : static int make_login_shell;            /* Make this shell be a `-bash' shell. */
     225             : static int want_initial_help;           /* --help option */
     226             : 
     227             : int debugging_mode = 0;         /* In debugging mode with --debugger */
     228             : #if defined (READLINE)
     229             : int no_line_editing = 0;        /* non-zero -> don't do fancy line editing. */
     230             : #else
     231             : int no_line_editing = 1;        /* can't have line editing without readline */
     232             : #endif
     233             : int dump_translatable_strings;  /* Dump strings in $"...", don't execute. */
     234             : int dump_po_strings;            /* Dump strings in $"..." in po format */
     235             : int wordexp_only = 0;           /* Do word expansion only */
     236             : int protected_mode = 0;         /* No command substitution with --wordexp */
     237             : 
     238             : #if defined (STRICT_POSIX)
     239             : int posixly_correct = 1;        /* Non-zero means posix.2 superset. */
     240             : #else
     241             : int posixly_correct = 0;        /* Non-zero means posix.2 superset. */
     242             : #endif
     243             : 
     244             : /* Some long-winded argument names.  These are obviously new. */
     245             : #define Int 1
     246             : #define Charp 2
     247             : static const struct {
     248             :   const char *name;
     249             :   int type;
     250             :   int *int_value;
     251             :   char **char_value;
     252             : } long_args[] = {
     253             :   { "debug", Int, &debugging, (char **)0x0 },
     254             : #if defined (DEBUGGER)
     255             :   { "debugger", Int, &debugging_mode, (char **)0x0 },
     256             : #endif
     257             :   { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 },
     258             :   { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 },
     259             :   { "help", Int, &want_initial_help, (char **)0x0 },
     260             :   { "init-file", Charp, (int *)0x0, &bashrc_file },
     261             :   { "login", Int, &make_login_shell, (char **)0x0 },
     262             :   { "noediting", Int, &no_line_editing, (char **)0x0 },
     263             :   { "noprofile", Int, &no_profile, (char **)0x0 },
     264             :   { "norc", Int, &no_rc, (char **)0x0 },
     265             :   { "posix", Int, &posixly_correct, (char **)0x0 },
     266             : #if defined (WORDEXP_OPTION)
     267             :   { "protected", Int, &protected_mode, (char **)0x0 },
     268             : #endif
     269             :   { "rcfile", Charp, (int *)0x0, &bashrc_file },
     270             :   { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
     271             : #if defined (RESTRICTED_SHELL)
     272             :   { "restricted", Int, &restricted, (char **)0x0 },
     273             : #endif
     274             :   { "verbose", Int, &verbose_flag, (char **)0x0 },
     275             :   { "version", Int, &do_version, (char **)0x0 },
     276             : #if defined (WORDEXP_OPTION)
     277             :   { "wordexp", Int, &wordexp_only, (char **)0x0 },
     278             : #endif
     279             :   { (char *)0x0, Int, (int *)0x0, (char **)0x0 }
     280             : };
     281             : 
     282             : /* These are extern so execute_simple_command can set them, and then
     283             :    longjmp back to main to execute a shell script, instead of calling
     284             :    main () again and resulting in indefinite, possibly fatal, stack
     285             :    growth. */
     286             : procenv_t subshell_top_level;
     287             : int subshell_argc;
     288             : char **subshell_argv;
     289             : char **subshell_envp;
     290             : 
     291             : char *exec_argv0;
     292             : 
     293             : #if defined (BUFFERED_INPUT)
     294             : /* The file descriptor from which the shell is reading input. */
     295             : int default_buffered_input = -1;
     296             : #endif
     297             : 
     298             : /* The following two variables are not static so they can show up in $-. */
     299             : int read_from_stdin;            /* -s flag supplied */
     300             : int want_pending_command;       /* -c flag supplied */
     301             : 
     302             : /* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */
     303             : char *command_execution_string; /* argument to -c option */
     304             : 
     305             : int malloc_trace_at_exit = 0;
     306             : 
     307             : static int shell_reinitialized = 0;
     308             : 
     309             : static FILE *default_input;
     310             : 
     311             : static STRING_INT_ALIST *shopt_alist;
     312             : static int shopt_ind = 0, shopt_len = 0;
     313             : 
     314             : static int parse_long_options __P((char **, int, int));
     315             : static int parse_shell_options __P((char **, int, int));
     316             : static int bind_args __P((char **, int, int, int));
     317             : 
     318             : static void start_debugger __P((void));
     319             : 
     320             : static void add_shopt_to_alist __P((char *, int));
     321             : static void run_shopt_alist __P((void));
     322             : 
     323             : static void execute_env_file __P((char *));
     324             : static void run_startup_files __P((void));
     325             : static int open_shell_script __P((char *));
     326             : static void set_bash_input __P((void));
     327             : static int run_one_command __P((char *));
     328             : #if defined (WORDEXP_OPTION)
     329             : static int run_wordexp __P((char *));
     330             : #endif
     331             : 
     332             : static int uidget __P((void));
     333             : 
     334             : static void init_interactive __P((void));
     335             : static void init_noninteractive __P((void));
     336             : static void init_interactive_script __P((void));
     337             : 
     338             : static void set_shell_name __P((char *));
     339             : static void shell_initialize __P((void));
     340             : static void shell_reinitialize __P((void));
     341             : 
     342             : static void show_shell_usage __P((FILE *, int));
     343             : 
     344             : #ifdef __CYGWIN__
     345             : static void
     346             : _cygwin32_check_tmp ()
     347             : {
     348             :   struct stat sb;
     349             : 
     350             :   if (stat ("/tmp", &sb) < 0)
     351             :     internal_warning (_("could not find /tmp, please create!"));
     352             :   else
     353             :     {
     354             :       if (S_ISDIR (sb.st_mode) == 0)
     355             :         internal_warning (_("/tmp must be a valid directory name"));
     356             :     }
     357             : }
     358             : #endif /* __CYGWIN__ */
     359             : 
     360             : #if defined (NO_MAIN_ENV_ARG)
     361             : /* systems without third argument to main() */
     362             : int
     363             : main (argc, argv)
     364             :      int argc;
     365             :      char **argv;
     366             : #else /* !NO_MAIN_ENV_ARG */
     367             : int
     368     9143291 : main (argc, argv, env)
     369             :      int argc;
     370             :      char **argv, **env;
     371             : #endif /* !NO_MAIN_ENV_ARG */
     372             : {
     373     9143291 :   register int i;
     374     9143291 :   int code, old_errexit_flag;
     375             : #if defined (RESTRICTED_SHELL)
     376     9143291 :   int saverst;
     377             : #endif
     378     9143291 :   volatile int locally_skip_execution;
     379     9143291 :   volatile int arg_index, top_level_arg_index;
     380             : #ifdef __OPENNT
     381             :   char **env;
     382             : 
     383             :   env = environ;
     384             : #endif /* __OPENNT */
     385             : 
     386     9143291 :   USE_VAR(argc);
     387     9143291 :   USE_VAR(argv);
     388     9143291 :   USE_VAR(env);
     389     9143291 :   USE_VAR(code);
     390     9143291 :   USE_VAR(old_errexit_flag);
     391             : #if defined (RESTRICTED_SHELL)
     392     9143291 :   USE_VAR(saverst);
     393             : #endif
     394             : 
     395             :   /* Catch early SIGINTs. */
     396     9143291 :   code = setjmp_nosigs (top_level);
     397     9143291 :   if (code)
     398           0 :     exit (2);
     399             : 
     400     9143291 :   xtrace_init ();
     401             : 
     402             : #if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
     403             :   malloc_set_register (1);      /* XXX - change to 1 for malloc debugging */
     404             : #endif
     405             : 
     406     9143291 :   check_dev_tty ();
     407             : 
     408             : #ifdef __CYGWIN__
     409             :   _cygwin32_check_tmp ();
     410             : #endif /* __CYGWIN__ */
     411             : 
     412             :   /* Wait forever if we are debugging a login shell. */
     413     9143291 :   while (debugging_login_shell) sleep (3);
     414             : 
     415     9143291 :   set_default_locale ();
     416             : 
     417     9143291 :   running_setuid = uidget ();
     418             : 
     419     9143291 :   if (getenv ("POSIXLY_CORRECT") || getenv ("POSIX_PEDANTIC"))
     420           0 :     posixly_correct = 1;
     421             : 
     422             : #if defined (USE_GNU_MALLOC_LIBRARY)
     423             :   mcheck (programming_error, (void (*) ())0);
     424             : #endif /* USE_GNU_MALLOC_LIBRARY */
     425             : 
     426     9143300 :   if (setjmp_sigs (subshell_top_level))
     427             :     {
     428           9 :       argc = subshell_argc;
     429           9 :       argv = subshell_argv;
     430           9 :       env = subshell_envp;
     431           9 :       sourced_env = 0;
     432             :     }
     433             : 
     434     9143300 :   shell_reinitialized = 0;
     435             : 
     436             :   /* Initialize `local' variables for all `invocations' of main (). */
     437     9143300 :   arg_index = 1;
     438     9143300 :   if (arg_index > argc)
     439           0 :     arg_index = argc;
     440     9143300 :   command_execution_string = (char *)NULL;
     441     9143300 :   want_pending_command = locally_skip_execution = read_from_stdin = 0;
     442     9143300 :   default_input = stdin;
     443             : #if defined (BUFFERED_INPUT)
     444     9143300 :   default_buffered_input = -1;
     445             : #endif
     446             : 
     447             :   /* Fix for the `infinite process creation' bug when running shell scripts
     448             :      from startup files on System V. */
     449     9143300 :   login_shell = make_login_shell = 0;
     450             : 
     451             :   /* If this shell has already been run, then reinitialize it to a
     452             :      vanilla state. */
     453     9143300 :   if (shell_initialized || shell_name)
     454             :     {
     455             :       /* Make sure that we do not infinitely recurse as a login shell. */
     456           9 :       if (*shell_name == '-')
     457           0 :         shell_name++;
     458             : 
     459           9 :       shell_reinitialize ();
     460           9 :       if (setjmp_nosigs (top_level))
     461           0 :         exit (2);
     462             :     }
     463             : 
     464     9143300 :   shell_environment = env;
     465     9143300 :   set_shell_name (argv[0]);
     466     9143300 :   shell_start_time = NOW;       /* NOW now defined in general.h */
     467             : 
     468             :   /* Parse argument flags from the input line. */
     469             : 
     470             :   /* Find full word arguments first. */
     471     9143300 :   arg_index = parse_long_options (argv, arg_index, argc);
     472             :   
     473     9143300 :   if (want_initial_help)
     474             :     {
     475           0 :       show_shell_usage (stdout, 1);
     476           0 :       exit (EXECUTION_SUCCESS);
     477             :     }
     478             : 
     479     9143300 :   if (do_version)
     480             :     {
     481           0 :       show_shell_version (1);
     482           0 :       exit (EXECUTION_SUCCESS);
     483             :     }
     484             : 
     485     9143300 :   echo_input_at_read = verbose_flag;    /* --verbose given */
     486             : 
     487             :   /* All done with full word options; do standard shell option parsing.*/
     488     9143300 :   this_command_name = shell_name;       /* for error reporting */
     489     9143300 :   arg_index = parse_shell_options (argv, arg_index, argc);
     490             : 
     491             :   /* If user supplied the "--login" (or -l) flag, then set and invert
     492             :      LOGIN_SHELL. */
     493     9143300 :   if (make_login_shell)
     494             :     {
     495           0 :       login_shell++;
     496           0 :       login_shell = -login_shell;
     497             :     }
     498             : 
     499     9143300 :   set_login_shell ("login_shell", login_shell != 0);
     500             : 
     501     9143300 :   if (dump_po_strings)
     502           0 :     dump_translatable_strings = 1;
     503             : 
     504     9143300 :   if (dump_translatable_strings)
     505           0 :     read_but_dont_execute = 1;
     506             : 
     507     9143300 :   if (rpm_requires)
     508             :     {
     509           0 :       read_but_dont_execute = 1;
     510           0 :       initialize_shell_builtins ();
     511             :     }
     512             : 
     513     9143300 :   if (running_setuid && privileged_mode == 0)
     514           0 :     disable_priv_mode ();
     515             : 
     516             :   /* Need to get the argument to a -c option processed in the
     517             :      above loop.  The next arg is a command to execute, and the
     518             :      following args are $0...$n respectively. */
     519     9143300 :   if (want_pending_command)
     520             :     {
     521           0 :       command_execution_string = argv[arg_index];
     522           0 :       if (command_execution_string == 0)
     523             :         {
     524           0 :           report_error (_("%s: option requires an argument"), "-c");
     525           0 :           exit (EX_BADUSAGE);
     526             :         }
     527           0 :       arg_index++;
     528             :     }
     529     9143300 :   this_command_name = (char *)NULL;
     530             : 
     531             :   /* First, let the outside world know about our interactive status.
     532             :      A shell is interactive if the `-i' flag was given, or if all of
     533             :      the following conditions are met:
     534             :         no -c command
     535             :         no arguments remaining or the -s flag given
     536             :         standard input is a terminal
     537             :         standard error is a terminal
     538             :      Refer to Posix.2, the description of the `sh' utility. */
     539             : 
     540     9143300 :   if (forced_interactive ||             /* -i flag */
     541     9143300 :       (!command_execution_string &&     /* No -c command and ... */
     542     9143300 :        wordexp_only == 0 &&             /* No --wordexp and ... */
     543     9143300 :        ((arg_index == argc) ||          /*   no remaining args or... */
     544     9143291 :         read_from_stdin) &&             /*   -s flag with args, and */
     545     9143291 :        isatty (fileno (stdin)) &&       /* Input is a terminal and */
     546           0 :        isatty (fileno (stderr))))       /* error output is a terminal. */
     547           0 :     init_interactive ();
     548             :   else
     549     9143300 :     init_noninteractive ();
     550             : 
     551             :   /*
     552             :    * Some systems have the bad habit of starting login shells with lots of open
     553             :    * file descriptors.  For instance, most systems that have picked up the
     554             :    * pre-4.0 Sun YP code leave a file descriptor open each time you call one
     555             :    * of the getpw* functions, and it's set to be open across execs.  That
     556             :    * means one for login, one for xterm, one for shelltool, etc.  There are
     557             :    * also systems that open persistent FDs to other agents or files as part
     558             :    * of process startup; these need to be set to be close-on-exec.
     559             :    */
     560     9143300 :   if (login_shell && interactive_shell)
     561             :     {
     562           0 :       for (i = 3; i < 20; i++)
     563           0 :         SET_CLOSE_ON_EXEC (i);
     564             :     }
     565             : 
     566             :   /* If we're in a strict Posix.2 mode, turn on interactive comments,
     567             :      alias expansion in non-interactive shells, and other Posix.2 things. */
     568     9143300 :   if (posixly_correct)
     569             :     {
     570           0 :       bind_variable ("POSIXLY_CORRECT", "y", 0);
     571           0 :       sv_strict_posix ("POSIXLY_CORRECT");
     572             :     }
     573             : 
     574             :   /* Now we run the shopt_alist and process the options. */
     575     9143300 :   if (shopt_alist)
     576           0 :     run_shopt_alist ();
     577             : 
     578             :   /* From here on in, the shell must be a normal functioning shell.
     579             :      Variables from the environment are expected to be set, etc. */
     580     9143300 :   shell_initialize ();
     581             : 
     582     9143300 :   set_default_lang ();
     583     9143300 :   set_default_locale_vars ();
     584             : 
     585             :   /*
     586             :    * M-x term -> TERM=eterm-color INSIDE_EMACS='251,term:0.96' (eterm)
     587             :    * M-x shell -> TERM='dumb' INSIDE_EMACS='25.1,comint' (no line editing)
     588             :    *
     589             :    * Older versions of Emacs may set EMACS to 't' or to something like
     590             :    * '22.1 (term:0.96)' instead of (or in addition to) setting INSIDE_EMACS.
     591             :    * They may set TERM to 'eterm' instead of 'eterm-color'.  They may have
     592             :    * a now-obsolete command that sets neither EMACS nor INSIDE_EMACS:
     593             :    * M-x terminal -> TERM='emacs-em7955' (line editing)
     594             :    */
     595     9143300 :   if (interactive_shell)
     596             :     {
     597           0 :       char *term, *emacs, *inside_emacs;;
     598           0 :       int emacs_term, in_emacs;
     599             : 
     600           0 :       term = get_string_value ("TERM");
     601           0 :       emacs = get_string_value ("EMACS");
     602           0 :       inside_emacs = get_string_value ("INSIDE_EMACS");
     603             : 
     604           0 :       if (inside_emacs)
     605             :         {
     606           0 :           emacs_term = strstr (inside_emacs, ",term:") != 0;
     607           0 :           in_emacs = 1;
     608             :         }
     609           0 :       else if (emacs)
     610             :         {
     611             :           /* Infer whether we are in an older Emacs. */
     612           0 :           emacs_term = strstr (emacs, " (term:") != 0;
     613           0 :           in_emacs = emacs_term || STREQ (emacs, "t");
     614             :         }
     615             :       else
     616             :         in_emacs = emacs_term = 0;
     617             : 
     618             :       /* Not sure any emacs terminal emulator sets TERM=emacs any more */
     619           0 :       no_line_editing |= STREQ (term, "emacs");
     620           0 :       no_line_editing |= in_emacs && STREQ (term, "dumb");
     621             : 
     622             :       /* running_under_emacs == 2 for `eterm' */
     623           0 :       running_under_emacs = in_emacs || STREQN (term, "emacs", 5);
     624           0 :       running_under_emacs += emacs_term && STREQN (term, "eterm", 5);
     625             : 
     626           0 :       if (running_under_emacs)
     627           0 :         gnu_error_format = 1;
     628             :     }
     629             : 
     630     9143300 :   top_level_arg_index = arg_index;
     631     9143300 :   old_errexit_flag = exit_immediately_on_error;
     632             : 
     633             :   /* Give this shell a place to longjmp to before executing the
     634             :      startup files.  This allows users to press C-c to abort the
     635             :      lengthy startup. */
     636     9143300 :   code = setjmp_sigs (top_level);
     637     9143300 :   if (code)
     638             :     {
     639           0 :       if (code == EXITPROG || code == ERREXIT)
     640           0 :         exit_shell (last_command_exit_value);
     641             :       else
     642             :         {
     643             : #if defined (JOB_CONTROL)
     644             :           /* Reset job control, since run_startup_files turned it off. */
     645           0 :           set_job_control (interactive_shell);
     646             : #endif
     647             :           /* Reset value of `set -e', since it's turned off before running
     648             :              the startup files. */
     649           0 :           exit_immediately_on_error += old_errexit_flag;
     650           0 :           locally_skip_execution++;
     651             :         }
     652             :     }
     653             : 
     654     9143300 :   arg_index = top_level_arg_index;
     655             : 
     656             :   /* Execute the start-up scripts. */
     657             : 
     658     9143300 :   if (interactive_shell == 0)
     659             :     {
     660     9143300 :       unbind_variable ("PS1");
     661     9143300 :       unbind_variable ("PS2");
     662     9143300 :       interactive = 0;
     663             : #if 0
     664             :       /* This has already been done by init_noninteractive */
     665             :       expand_aliases = posixly_correct;
     666             : #endif
     667             :     }
     668             :   else
     669             :     {
     670           0 :       change_flag ('i', FLAG_ON);
     671           0 :       interactive = 1;
     672             :     }
     673             : 
     674             : #if defined (RESTRICTED_SHELL)
     675             :   /* Set restricted_shell based on whether the basename of $0 indicates that
     676             :      the shell should be restricted or if the `-r' option was supplied at
     677             :      startup. */
     678     9143300 :   restricted_shell = shell_is_restricted (shell_name);
     679             : 
     680             :   /* If the `-r' option is supplied at invocation, make sure that the shell
     681             :      is not in restricted mode when running the startup files. */
     682     9143300 :   saverst = restricted;
     683     9143300 :   restricted = 0;
     684             : #endif
     685             : 
     686             :   /* The startup files are run with `set -e' temporarily disabled. */
     687     9143300 :   if (locally_skip_execution == 0 && running_setuid == 0)
     688             :     {
     689     9143300 :       old_errexit_flag = exit_immediately_on_error;
     690     9143300 :       exit_immediately_on_error = 0;
     691             : 
     692     9143300 :       run_startup_files ();
     693     9143300 :       exit_immediately_on_error += old_errexit_flag;
     694             :     }
     695             : 
     696             :   /* If we are invoked as `sh', turn on Posix mode. */
     697     9143300 :   if (act_like_sh)
     698             :     {
     699           0 :       bind_variable ("POSIXLY_CORRECT", "y", 0);
     700           0 :       sv_strict_posix ("POSIXLY_CORRECT");
     701             :     }
     702             : 
     703             : #if defined (RESTRICTED_SHELL)
     704             :   /* Turn on the restrictions after executing the startup files.  This
     705             :      means that `bash -r' or `set -r' invoked from a startup file will
     706             :      turn on the restrictions after the startup files are executed. */
     707     9143300 :   restricted = saverst || restricted;
     708     9143300 :   if (shell_reinitialized == 0)
     709     9143291 :     maybe_make_restricted (shell_name);
     710             : #endif /* RESTRICTED_SHELL */
     711             : 
     712             : #if defined (WORDEXP_OPTION)
     713             :   if (wordexp_only)
     714             :     {
     715             :       startup_state = 3;
     716             :       last_command_exit_value = run_wordexp (argv[arg_index]);
     717             :       exit_shell (last_command_exit_value);
     718             :     }
     719             : #endif
     720             : 
     721     9143300 :   cmd_init ();          /* initialize the command object caches */
     722     9143300 :   uwp_init ();
     723             : 
     724     9143300 :   if (command_execution_string)
     725             :     {
     726           0 :       arg_index = bind_args (argv, arg_index, argc, 0);
     727           0 :       startup_state = 2;
     728             : 
     729           0 :       if (debugging_mode)
     730           0 :         start_debugger ();
     731             : 
     732             : #if defined (ONESHOT)
     733           0 :       executing = 1;
     734           0 :       run_one_command (command_execution_string);
     735           0 :       exit_shell (last_command_exit_value);
     736             : #else /* ONESHOT */
     737             :       with_input_from_string (command_execution_string, "-c");
     738             :       goto read_and_execute;
     739             : #endif /* !ONESHOT */
     740             :     }
     741             : 
     742             :   /* Get possible input filename and set up default_buffered_input or
     743             :      default_input as appropriate. */
     744     9143300 :   if (arg_index != argc && read_from_stdin == 0)
     745             :     {
     746           9 :       open_shell_script (argv[arg_index]);
     747           9 :       arg_index++;
     748             :     }
     749     9143291 :   else if (interactive == 0)
     750             :     {
     751             :       /* In this mode, bash is reading a script from stdin, which is a
     752             :          pipe or redirected file. */
     753             : #if defined (BUFFERED_INPUT)
     754     9143291 :       default_buffered_input = fileno (stdin);  /* == 0 */
     755             : #else
     756             :       setbuf (default_input, (char *)NULL);
     757             : #endif /* !BUFFERED_INPUT */
     758     9143291 :       read_from_stdin = 1;
     759             :     }
     760           0 :   else if (arg_index == argc)
     761             :     /* "If there are no operands and the -c option is not specified, the -s
     762             :        option shall be assumed." */
     763           0 :     read_from_stdin = 1;
     764             : 
     765     9143300 :   set_bash_input ();
     766             : 
     767             :   /* Bind remaining args to $1 ... $n */
     768     9143300 :   arg_index = bind_args (argv, arg_index, argc, 1);
     769             : 
     770     9143300 :   if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0 && (reading_shell_script || interactive_shell == 0))
     771           0 :     start_debugger ();
     772             : 
     773             :   /* Do the things that should be done only for interactive shells. */
     774     9143300 :   if (interactive_shell)
     775             :     {
     776             :       /* Set up for checking for presence of mail. */
     777           0 :       reset_mail_timer ();
     778           0 :       init_mail_dates ();
     779             : 
     780             : #if defined (HISTORY)
     781             :       /* Initialize the interactive history stuff. */
     782           0 :       bash_initialize_history ();
     783             :       /* Don't load the history from the history file if we've already
     784             :          saved some lines in this session (e.g., by putting `history -s xx'
     785             :          into one of the startup files). */
     786           0 :       if (shell_initialized == 0 && history_lines_this_session == 0)
     787           0 :         load_history ();
     788             : #endif /* HISTORY */
     789             : 
     790             :       /* Initialize terminal state for interactive shells after the
     791             :          .bash_profile and .bashrc are interpreted. */
     792           0 :       get_tty_state ();
     793             :     }
     794             : 
     795             : #if !defined (ONESHOT)
     796             :  read_and_execute:
     797             : #endif /* !ONESHOT */
     798             : 
     799     9143300 :   shell_initialized = 1;
     800             : 
     801             :   /* Read commands until exit condition. */
     802     9143300 :   reader_loop ();
     803     9143350 :   exit_shell (last_command_exit_value);
     804             : }
     805             : 
     806             : static int
     807     9143300 : parse_long_options (argv, arg_start, arg_end)
     808             :      char **argv;
     809             :      int arg_start, arg_end;
     810             : {
     811     9143300 :   int arg_index, longarg, i;
     812     9143300 :   char *arg_string;
     813             : 
     814     9143300 :   arg_index = arg_start;
     815     9143300 :   while ((arg_index != arg_end) && (arg_string = argv[arg_index]) &&
     816           9 :          (*arg_string == '-'))
     817             :     {
     818           0 :       longarg = 0;
     819             : 
     820             :       /* Make --login equivalent to -login. */
     821           0 :       if (arg_string[1] == '-' && arg_string[2])
     822             :         {
     823           0 :           longarg = 1;
     824           0 :           arg_string++;
     825             :         }
     826             : 
     827           0 :       for (i = 0; long_args[i].name; i++)
     828             :         {
     829           0 :           if (STREQ (arg_string + 1, long_args[i].name))
     830             :             {
     831           0 :               if (long_args[i].type == Int)
     832           0 :                 *long_args[i].int_value = 1;
     833           0 :               else if (argv[++arg_index] == 0)
     834             :                 {
     835           0 :                   report_error (_("%s: option requires an argument"), long_args[i].name);
     836           0 :                   exit (EX_BADUSAGE);
     837             :                 }
     838             :               else
     839           0 :                 *long_args[i].char_value = argv[arg_index];
     840             : 
     841             :               break;
     842             :             }
     843             :         }
     844           0 :       if (long_args[i].name == 0)
     845             :         {
     846           0 :           if (longarg)
     847             :             {
     848           0 :               report_error (_("%s: invalid option"), argv[arg_index]);
     849           0 :               show_shell_usage (stderr, 0);
     850           0 :               exit (EX_BADUSAGE);
     851             :             }
     852             :           break;                /* No such argument.  Maybe flag arg. */
     853             :         }
     854             : 
     855           0 :       arg_index++;
     856             :     }
     857             : 
     858     9143300 :   return (arg_index);
     859             : }
     860             : 
     861             : static int
     862     9143300 : parse_shell_options (argv, arg_start, arg_end)
     863             :      char **argv;
     864             :      int arg_start, arg_end;
     865             : {
     866     9143300 :   int arg_index;
     867     9143300 :   int arg_character, on_or_off, next_arg, i;
     868     9143300 :   char *o_option, *arg_string;
     869             : 
     870     9143300 :   arg_index = arg_start;
     871     9143300 :   while (arg_index != arg_end && (arg_string = argv[arg_index]) &&
     872           9 :          (*arg_string == '-' || *arg_string == '+'))
     873             :     {
     874             :       /* There are flag arguments, so parse them. */
     875           0 :       next_arg = arg_index + 1;
     876             : 
     877             :       /* A single `-' signals the end of options.  From the 4.3 BSD sh.
     878             :          An option `--' means the same thing; this is the standard
     879             :          getopt(3) meaning. */
     880           0 :       if (arg_string[0] == '-' &&
     881           0 :            (arg_string[1] == '\0' ||
     882           0 :              (arg_string[1] == '-' && arg_string[2] == '\0')))
     883           0 :         return (next_arg);
     884             : 
     885           0 :       i = 1;
     886           0 :       on_or_off = arg_string[0];
     887           0 :       while (arg_character = arg_string[i++])
     888             :         {
     889           0 :           switch (arg_character)
     890             :             {
     891           0 :             case 'c':
     892           0 :               want_pending_command = 1;
     893           0 :               break;
     894             : 
     895           0 :             case 'l':
     896           0 :               make_login_shell = 1;
     897           0 :               break;
     898             : 
     899           0 :             case 's':
     900           0 :               read_from_stdin = 1;
     901           0 :               break;
     902             : 
     903           0 :             case 'o':
     904           0 :               o_option = argv[next_arg];
     905           0 :               if (o_option == 0)
     906             :                 {
     907           0 :                   list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1);
     908           0 :                   break;
     909             :                 }
     910           0 :               if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
     911           0 :                 exit (EX_BADUSAGE);
     912           0 :               next_arg++;
     913           0 :               break;
     914             : 
     915           0 :             case 'O':
     916             :               /* Since some of these can be overridden by the normal
     917             :                  interactive/non-interactive shell initialization or
     918             :                  initializing posix mode, we save the options and process
     919             :                  them after initialization. */
     920           0 :               o_option = argv[next_arg];
     921           0 :               if (o_option == 0)
     922             :                 {
     923           0 :                   shopt_listopt (o_option, (on_or_off == '-') ? 0 : 1);
     924           0 :                   break;
     925             :                 }
     926           0 :               add_shopt_to_alist (o_option, on_or_off);
     927           0 :               next_arg++;
     928           0 :               break;
     929             : 
     930           0 :             case 'D':
     931           0 :               dump_translatable_strings = 1;
     932           0 :               break;
     933             : 
     934           0 :             default:
     935           0 :               if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
     936             :                 {
     937           0 :                   report_error (_("%c%c: invalid option"), on_or_off, arg_character);
     938           0 :                   show_shell_usage (stderr, 0);
     939           0 :                   exit (EX_BADUSAGE);
     940             :                 }
     941             :             }
     942             :         }
     943             :       /* Can't do just a simple increment anymore -- what about
     944             :          "bash -abouo emacs ignoreeof -hP"? */
     945             :       arg_index = next_arg;
     946             :     }
     947             : 
     948             :   return (arg_index);
     949             : }
     950             : 
     951             : /* Exit the shell with status S. */
     952             : void
     953     9143350 : exit_shell (s)
     954             :      int s;
     955             : {
     956     9143350 :   fflush (stdout);              /* XXX */
     957     9143350 :   fflush (stderr);
     958             : 
     959             :   /* Clean up the terminal if we are in a state where it's been modified. */
     960             : #if defined (READLINE)
     961     9143350 :   if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
     962           0 :     (*rl_deprep_term_function) ();
     963             : #endif
     964     9143350 :   if (read_tty_modified ())
     965           0 :     read_tty_cleanup ();
     966             : 
     967             :   /* Do trap[0] if defined.  Allow it to override the exit status
     968             :      passed to us. */
     969     9143350 :   if (signal_is_trapped (0))
     970           9 :     s = run_exit_trap ();
     971             : 
     972             : #if defined (PROCESS_SUBSTITUTION)
     973     9143350 :   unlink_fifo_list ();
     974             : #endif /* PROCESS_SUBSTITUTION */
     975             : 
     976             : #if defined (HISTORY)
     977     9143350 :   if (remember_on_history)
     978           0 :     maybe_save_shell_history ();
     979             : #endif /* HISTORY */
     980             : 
     981             : #if defined (COPROCESS_SUPPORT)
     982     9143350 :   coproc_flush ();
     983             : #endif
     984             : 
     985             : #if defined (JOB_CONTROL)
     986             :   /* If the user has run `shopt -s huponexit', hangup all jobs when we exit
     987             :      an interactive login shell.  ksh does this unconditionally. */
     988     9143350 :   if (interactive_shell && login_shell && hup_on_exit)
     989           0 :     hangup_all_jobs ();
     990             : 
     991             :   /* If this shell is interactive, or job control is active, terminate all
     992             :      stopped jobs and restore the original terminal process group.  Don't do
     993             :      this if we're in a subshell and calling exit_shell after, for example,
     994             :      a failed word expansion.  We want to do this even if the shell is not
     995             :      interactive because we set the terminal's process group when job control
     996             :      is enabled regardless of the interactive status. */
     997     9143350 :   if (subshell_environment == 0)
     998     9143256 :     end_job_control ();
     999             : #endif /* JOB_CONTROL */
    1000             : 
    1001             :   /* Always return the exit status of the last command to our parent. */
    1002     9143350 :   sh_exit (s);
    1003             : }
    1004             : 
    1005             : /* A wrapper for exit that (optionally) can do other things, like malloc
    1006             :    statistics tracing. */
    1007             : void
    1008       11062 : sh_exit (s)
    1009             :      int s;
    1010             : {
    1011             : #if defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC)
    1012             :   if (malloc_trace_at_exit)
    1013             :     trace_malloc_stats (get_name_for_error (), (char *)NULL);
    1014             :   /* mlocation_write_table (); */
    1015             : #endif
    1016             : 
    1017     9154412 :   exit (s);
    1018             : }
    1019             : 
    1020             : /* Exit a subshell, which includes calling the exit trap.  We don't want to
    1021             :    do any more cleanup, since a subshell is created as an exact copy of its
    1022             :    parent. */
    1023             : void
    1024           0 : subshell_exit (s)
    1025             :      int s;
    1026             : {
    1027           0 :   fflush (stdout);
    1028           0 :   fflush (stderr);
    1029             : 
    1030             :   /* Do trap[0] if defined.  Allow it to override the exit status
    1031             :      passed to us. */
    1032           0 :   if (signal_is_trapped (0))
    1033           0 :     s = run_exit_trap ();
    1034             : 
    1035           0 :   sh_exit (s);
    1036             : }
    1037             : 
    1038             : /* Source the bash startup files.  If POSIXLY_CORRECT is non-zero, we obey
    1039             :    the Posix.2 startup file rules:  $ENV is expanded, and if the file it
    1040             :    names exists, that file is sourced.  The Posix.2 rules are in effect
    1041             :    for interactive shells only. (section 4.56.5.3) */
    1042             : 
    1043             : /* Execute ~/.bashrc for most shells.  Never execute it if
    1044             :    ACT_LIKE_SH is set, or if NO_RC is set.
    1045             : 
    1046             :    If the executable file "/usr/gnu/src/bash/foo" contains:
    1047             : 
    1048             :    #!/usr/gnu/bin/bash
    1049             :    echo hello
    1050             : 
    1051             :    then:
    1052             : 
    1053             :          COMMAND            EXECUTE BASHRC
    1054             :          --------------------------------
    1055             :          bash -c foo            NO
    1056             :          bash foo               NO
    1057             :          foo                    NO
    1058             :          rsh machine ls         YES (for rsh, which calls `bash -c')
    1059             :          rsh machine foo        YES (for shell started by rsh) NO (for foo!)
    1060             :          echo ls | bash         NO
    1061             :          login                  NO
    1062             :          bash                   YES
    1063             : */
    1064             : 
    1065             : static void
    1066     9143300 : execute_env_file (env_file)
    1067             :       char *env_file;
    1068             : {
    1069     9143300 :   char *fn;
    1070             : 
    1071     9143300 :   if (env_file && *env_file)
    1072             :     {
    1073     9143300 :       fn = expand_string_unsplit_to_string (env_file, Q_DOUBLE_QUOTES);
    1074     9143300 :       if (fn && *fn)
    1075     9143300 :         maybe_execute_file (fn, 1);
    1076     9143300 :       FREE (fn);
    1077             :     }
    1078     9143300 : }
    1079             : 
    1080             : static void
    1081     9143300 : run_startup_files ()
    1082             : {
    1083             : #if defined (JOB_CONTROL)
    1084     9143300 :   int old_job_control;
    1085             : #endif
    1086     9143300 :   int sourced_login, run_by_ssh;
    1087             : 
    1088             :   /* get the rshd/sshd case out of the way first. */
    1089     9143300 :   if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
    1090     9143291 :       act_like_sh == 0 && command_execution_string)
    1091             :     {
    1092             : #ifdef SSH_SOURCE_BASHRC
    1093           0 :       run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) ||
    1094           0 :                    (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0);
    1095             : #else
    1096             :       run_by_ssh = 0;
    1097             : #endif
    1098             : 
    1099             :       /* If we were run by sshd or we think we were run by rshd, execute
    1100             :          ~/.bashrc if we are a top-level shell. */
    1101           0 :       if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
    1102             :         {
    1103             : #ifdef SYS_BASHRC
    1104             : #  if defined (__OPENNT)
    1105             :           maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
    1106             : #  else
    1107             :           maybe_execute_file (SYS_BASHRC, 1);
    1108             : #  endif
    1109             : #endif
    1110           0 :           maybe_execute_file (bashrc_file, 1);
    1111           0 :           return;
    1112             :         }
    1113             :     }
    1114             : 
    1115             : #if defined (JOB_CONTROL)
    1116             :   /* Startup files should be run without job control enabled. */
    1117     9143300 :   old_job_control = interactive_shell ? set_job_control (0) : 0;
    1118             : #endif
    1119             : 
    1120     9143300 :   sourced_login = 0;
    1121             : 
    1122             :   /* A shell begun with the --login (or -l) flag that is not in posix mode
    1123             :      runs the login shell startup files, no matter whether or not it is
    1124             :      interactive.  If NON_INTERACTIVE_LOGIN_SHELLS is defined, run the
    1125             :      startup files if argv[0][0] == '-' as well. */
    1126             : #if defined (NON_INTERACTIVE_LOGIN_SHELLS)
    1127     9143300 :   if (login_shell && posixly_correct == 0)
    1128             : #else
    1129             :   if (login_shell < 0 && posixly_correct == 0)
    1130             : #endif
    1131             :     {
    1132             :       /* We don't execute .bashrc for login shells. */
    1133           0 :       no_rc++;
    1134             : 
    1135             :       /* Execute /etc/profile and one of the personal login shell
    1136             :          initialization files. */
    1137           0 :       if (no_profile == 0)
    1138             :         {
    1139           0 :           maybe_execute_file (SYS_PROFILE, 1);
    1140             : 
    1141           0 :           if (act_like_sh)      /* sh */
    1142           0 :             maybe_execute_file ("~/.profile", 1);
    1143           0 :           else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
    1144           0 :                    (maybe_execute_file ("~/.bash_login", 1) == 0))    /* bash */
    1145           0 :             maybe_execute_file ("~/.profile", 1);
    1146             :         }
    1147             : 
    1148             :       sourced_login = 1;
    1149             :     }
    1150             : 
    1151             :   /* A non-interactive shell not named `sh' and not in posix mode reads and
    1152             :      executes commands from $BASH_ENV.  If `su' starts a shell with `-c cmd'
    1153             :      and `-su' as the name of the shell, we want to read the startup files.
    1154             :      No other non-interactive shells read any startup files. */
    1155     9143300 :   if (interactive_shell == 0 && !(su_shell && login_shell))
    1156             :     {
    1157     9143300 :       if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 &&
    1158     9143300 :             sourced_env++ == 0)
    1159     9143300 :         execute_env_file (get_string_value ("BASH_ENV"));
    1160     9143300 :       return;
    1161             :     }
    1162             : 
    1163             :   /* Interactive shell or `-su' shell. */
    1164           0 :   if (posixly_correct == 0)               /* bash, sh */
    1165             :     {
    1166           0 :       if (login_shell && sourced_login++ == 0)
    1167             :         {
    1168             :           /* We don't execute .bashrc for login shells. */
    1169           0 :           no_rc++;
    1170             : 
    1171             :           /* Execute /etc/profile and one of the personal login shell
    1172             :              initialization files. */
    1173           0 :           if (no_profile == 0)
    1174             :             {
    1175           0 :               maybe_execute_file (SYS_PROFILE, 1);
    1176             : 
    1177           0 :               if (act_like_sh)  /* sh */
    1178           0 :                 maybe_execute_file ("~/.profile", 1);
    1179           0 :               else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
    1180           0 :                        (maybe_execute_file ("~/.bash_login", 1) == 0))        /* bash */
    1181           0 :                 maybe_execute_file ("~/.profile", 1);
    1182             :             }
    1183             :         }
    1184             : 
    1185             :       /* bash */
    1186           0 :       if (act_like_sh == 0 && no_rc == 0)
    1187             :         {
    1188             : #ifdef SYS_BASHRC
    1189             : #  if defined (__OPENNT)
    1190             :           maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
    1191             : #  else
    1192             :           maybe_execute_file (SYS_BASHRC, 1);
    1193             : #  endif
    1194             : #endif
    1195           0 :           maybe_execute_file (bashrc_file, 1);
    1196             :         }
    1197             :       /* sh */
    1198           0 :       else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
    1199           0 :         execute_env_file (get_string_value ("ENV"));
    1200             :     }
    1201             :   else          /* bash --posix, sh --posix */
    1202             :     {
    1203             :       /* bash and sh */
    1204           0 :       if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
    1205           0 :         execute_env_file (get_string_value ("ENV"));
    1206             :     }
    1207             : 
    1208             : #if defined (JOB_CONTROL)
    1209           0 :   set_job_control (old_job_control);
    1210             : #endif
    1211             : }
    1212             : 
    1213             : #if defined (RESTRICTED_SHELL)
    1214             : /* Return 1 if the shell should be a restricted one based on NAME or the
    1215             :    value of `restricted'.  Don't actually do anything, just return a
    1216             :    boolean value. */
    1217             : int
    1218    18286600 : shell_is_restricted (name)
    1219             :      char *name;
    1220             : {
    1221    18286600 :   char *temp;
    1222             : 
    1223    18286600 :   if (restricted)
    1224             :     return 1;
    1225    18286600 :   temp = base_pathname (name);
    1226    18286600 :   if (*temp == '-')
    1227           0 :     temp++;
    1228    18286600 :   return (STREQ (temp, RESTRICTED_SHELL_NAME));
    1229             : }
    1230             : 
    1231             : /* Perhaps make this shell a `restricted' one, based on NAME.  If the
    1232             :    basename of NAME is "rbash", then this shell is restricted.  The
    1233             :    name of the restricted shell is a configurable option, see config.h.
    1234             :    In a restricted shell, PATH, SHELL, ENV, and BASH_ENV are read-only
    1235             :    and non-unsettable.
    1236             :    Do this also if `restricted' is already set to 1; maybe the shell was
    1237             :    started with -r. */
    1238             : int
    1239     9143291 : maybe_make_restricted (name)
    1240             :      char *name;
    1241             : {
    1242     9143291 :   char *temp;
    1243             : 
    1244     9143291 :   temp = base_pathname (name);
    1245     9143291 :   if (*temp == '-')
    1246           0 :     temp++;
    1247     9143291 :   if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
    1248             :     {
    1249           0 :       set_var_read_only ("PATH");
    1250           0 :       set_var_read_only ("SHELL");
    1251           0 :       set_var_read_only ("ENV");
    1252           0 :       set_var_read_only ("BASH_ENV");
    1253           0 :       restricted = 1;
    1254             :     }
    1255     9143291 :   return (restricted);
    1256             : }
    1257             : #endif /* RESTRICTED_SHELL */
    1258             : 
    1259             : /* Fetch the current set of uids and gids and return 1 if we're running
    1260             :    setuid or setgid. */
    1261             : static int
    1262     9143291 : uidget ()
    1263             : {
    1264     9143291 :   uid_t u;
    1265             : 
    1266     9143291 :   u = getuid ();
    1267     9143291 :   if (current_user.uid != u)
    1268             :     {
    1269     9143291 :       FREE (current_user.user_name);
    1270     9143291 :       FREE (current_user.shell);
    1271     9143291 :       FREE (current_user.home_dir);
    1272     9143291 :       current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL;
    1273             :     }
    1274     9143291 :   current_user.uid = u;
    1275     9143291 :   current_user.gid = getgid ();
    1276     9143291 :   current_user.euid = geteuid ();
    1277     9143291 :   current_user.egid = getegid ();
    1278             : 
    1279             :   /* See whether or not we are running setuid or setgid. */
    1280     9143291 :   return (current_user.uid != current_user.euid) ||
    1281     9143291 :            (current_user.gid != current_user.egid);
    1282             : }
    1283             : 
    1284             : void
    1285           0 : disable_priv_mode ()
    1286             : {
    1287           0 :   int e;
    1288             : 
    1289           0 :   if (setuid (current_user.uid) < 0)
    1290             :     {
    1291           0 :       e = errno;
    1292           0 :       sys_error (_("cannot set uid to %d: effective uid %d"), current_user.uid, current_user.euid);
    1293             : #if defined (EXIT_ON_SETUID_FAILURE)
    1294           0 :       if (e == EAGAIN)
    1295           0 :         exit (e);
    1296             : #endif
    1297             :     }
    1298           0 :   if (setgid (current_user.gid) < 0)
    1299           0 :     sys_error (_("cannot set gid to %d: effective gid %d"), current_user.gid, current_user.egid);
    1300             : 
    1301           0 :   current_user.euid = current_user.uid;
    1302           0 :   current_user.egid = current_user.gid;
    1303           0 : }
    1304             : 
    1305             : #if defined (WORDEXP_OPTION)
    1306             : static int
    1307             : run_wordexp (words)
    1308             :      char *words;
    1309             : {
    1310             :   int code, nw, nb;
    1311             :   WORD_LIST *wl, *tl, *result;
    1312             : 
    1313             :   code = setjmp_nosigs (top_level);
    1314             : 
    1315             :   if (code != NOT_JUMPED)
    1316             :     {
    1317             :       switch (code)
    1318             :         {
    1319             :           /* Some kind of throw to top_level has occurred. */
    1320             :         case FORCE_EOF:
    1321             :           return last_command_exit_value = 127;
    1322             :         case ERREXIT:
    1323             :         case EXITPROG:
    1324             :           return last_command_exit_value;
    1325             :         case DISCARD:
    1326             :           return last_command_exit_value = 1;
    1327             :         default:
    1328             :           command_error ("run_wordexp", CMDERR_BADJUMP, code, 0);
    1329             :         }
    1330             :     }
    1331             : 
    1332             :   /* Run it through the parser to get a list of words and expand them */
    1333             :   if (words && *words)
    1334             :     {
    1335             :       with_input_from_string (words, "--wordexp");
    1336             :       if (parse_command () != 0)
    1337             :         return (126);
    1338             :       if (global_command == 0)
    1339             :         {
    1340             :           printf ("0\n0\n");
    1341             :           return (0);
    1342             :         }
    1343             :       if (global_command->type != cm_simple)
    1344             :         return (126);
    1345             :       wl = global_command->value.Simple->words;
    1346             :       if (protected_mode)
    1347             :         for (tl = wl; tl; tl = tl->next)
    1348             :           tl->word->flags |= W_NOCOMSUB|W_NOPROCSUB;
    1349             :       result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0;
    1350             :     }
    1351             :   else
    1352             :     result = (WORD_LIST *)0;
    1353             : 
    1354             :   last_command_exit_value = 0;
    1355             : 
    1356             :   if (result == 0)
    1357             :     {
    1358             :       printf ("0\n0\n");
    1359             :       return (0);
    1360             :     }
    1361             : 
    1362             :   /* Count up the number of words and bytes, and print them.  Don't count
    1363             :      the trailing NUL byte. */
    1364             :   for (nw = nb = 0, wl = result; wl; wl = wl->next)
    1365             :     {
    1366             :       nw++;
    1367             :       nb += strlen (wl->word->word);
    1368             :     }
    1369             :   printf ("%u\n%u\n", nw, nb);
    1370             :   /* Print each word on a separate line.  This will have to be changed when
    1371             :      the interface to glibc is completed. */
    1372             :   for (wl = result; wl; wl = wl->next)
    1373             :     printf ("%s\n", wl->word->word);
    1374             : 
    1375             :   return (0);
    1376             : }
    1377             : #endif
    1378             : 
    1379             : #if defined (ONESHOT)
    1380             : /* Run one command, given as the argument to the -c option.  Tell
    1381             :    parse_and_execute not to fork for a simple command. */
    1382             : static int
    1383           0 : run_one_command (command)
    1384             :      char *command;
    1385             : {
    1386           0 :   int code;
    1387             : 
    1388           0 :   code = setjmp_nosigs (top_level);
    1389             : 
    1390           0 :   if (code != NOT_JUMPED)
    1391             :     {
    1392             : #if defined (PROCESS_SUBSTITUTION)
    1393           0 :       unlink_fifo_list ();
    1394             : #endif /* PROCESS_SUBSTITUTION */
    1395           0 :       switch (code)
    1396             :         {
    1397             :           /* Some kind of throw to top_level has occurred. */
    1398           0 :         case FORCE_EOF:
    1399           0 :           return last_command_exit_value = 127;
    1400           0 :         case ERREXIT:
    1401             :         case EXITPROG:
    1402           0 :           return last_command_exit_value;
    1403           0 :         case DISCARD:
    1404           0 :           return last_command_exit_value = 1;
    1405           0 :         default:
    1406           0 :           command_error ("run_one_command", CMDERR_BADJUMP, code, 0);
    1407             :         }
    1408             :     }
    1409           0 :    return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST));
    1410             : }
    1411             : #endif /* ONESHOT */
    1412             : 
    1413             : static int
    1414     9143300 : bind_args (argv, arg_start, arg_end, start_index)
    1415             :      char **argv;
    1416             :      int arg_start, arg_end, start_index;
    1417             : {
    1418     9143300 :   register int i;
    1419     9143300 :   WORD_LIST *args;
    1420             : 
    1421     9143300 :   for (i = arg_start, args = (WORD_LIST *)NULL; i < arg_end; i++)
    1422           0 :     args = make_word_list (make_word (argv[i]), args);
    1423     9143300 :   if (args)
    1424             :     {
    1425           0 :       args = REVERSE_LIST (args, WORD_LIST *);
    1426           0 :       if (start_index == 0)     /* bind to $0...$n for sh -c command */
    1427             :         {
    1428             :           /* Posix.2 4.56.3 says that the first argument after sh -c command
    1429             :              becomes $0, and the rest of the arguments become $1...$n */
    1430           0 :           shell_name = savestring (args->word->word);
    1431           0 :           FREE (dollar_vars[0]);
    1432           0 :           dollar_vars[0] = savestring (args->word->word);
    1433           0 :           remember_args (args->next, 1);
    1434           0 :           push_args (args->next);    /* BASH_ARGV and BASH_ARGC */
    1435             :         }
    1436             :       else                      /* bind to $1...$n for shell script */
    1437             :         {
    1438           0 :           remember_args (args, 1);
    1439           0 :           push_args (args);             /* BASH_ARGV and BASH_ARGC */
    1440             :         }
    1441             : 
    1442           0 :       dispose_words (args);
    1443             :     }
    1444             : 
    1445     9143300 :   return (i);
    1446             : }
    1447             : 
    1448             : void
    1449           9 : unbind_args ()
    1450             : {
    1451           9 :   remember_args ((WORD_LIST *)NULL, 1);
    1452           9 :   pop_args ();                          /* Reset BASH_ARGV and BASH_ARGC */
    1453           9 : }
    1454             : 
    1455             : static void
    1456           0 : start_debugger ()
    1457             : {
    1458             : #if defined (DEBUGGER) && defined (DEBUGGER_START_FILE)
    1459           0 :   int old_errexit;
    1460           0 :   int r;
    1461             : 
    1462           0 :   old_errexit = exit_immediately_on_error;
    1463           0 :   exit_immediately_on_error = 0;
    1464             : 
    1465           0 :   r = force_execute_file (DEBUGGER_START_FILE, 1);
    1466           0 :   if (r < 0)
    1467             :     {
    1468           0 :       internal_warning (_("cannot start debugger; debugging mode disabled"));
    1469           0 :       debugging_mode = 0;
    1470             :     }
    1471           0 :   error_trace_mode = function_trace_mode = debugging_mode;
    1472             : 
    1473           0 :   set_shellopts ();
    1474           0 :   set_bashopts ();
    1475             : 
    1476           0 :   exit_immediately_on_error += old_errexit;
    1477             : #endif
    1478           0 : }
    1479             : 
    1480             : static int
    1481           9 : open_shell_script (script_name)
    1482             :      char *script_name;
    1483             : {
    1484           9 :   int fd, e, fd_is_tty;
    1485           9 :   char *filename, *path_filename, *t;
    1486           9 :   char sample[80];
    1487           9 :   int sample_len;
    1488           9 :   struct stat sb;
    1489             : #if defined (ARRAY_VARS)
    1490           9 :   SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
    1491           9 :   ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
    1492             : #endif
    1493             : 
    1494           9 :   filename = savestring (script_name);
    1495             : 
    1496           9 :   fd = open (filename, O_RDONLY);
    1497           9 :   if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
    1498             :     {
    1499           0 :       e = errno;
    1500             :       /* If it's not in the current directory, try looking through PATH
    1501             :          for it. */
    1502           0 :       path_filename = find_path_file (script_name);
    1503           0 :       if (path_filename)
    1504             :         {
    1505           0 :           free (filename);
    1506           0 :           filename = path_filename;
    1507           0 :           fd = open (filename, O_RDONLY);
    1508             :         }
    1509             :       else
    1510           0 :         errno = e;
    1511             :     }
    1512             : 
    1513           9 :   if (fd < 0)
    1514             :     {
    1515           0 :       e = errno;
    1516           0 :       file_error (filename);
    1517           0 :       sh_exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
    1518             :     }
    1519             : 
    1520           9 :   free (dollar_vars[0]);
    1521           9 :   dollar_vars[0] = exec_argv0 ? savestring (exec_argv0) : savestring (script_name);
    1522           9 :   if (exec_argv0)
    1523             :     {
    1524           0 :       free (exec_argv0);
    1525           0 :       exec_argv0 = (char *)NULL;
    1526             :     }
    1527             : 
    1528           9 :   if (file_isdir (filename))
    1529             :     {
    1530             : #if defined (EISDIR)
    1531           0 :       errno = EISDIR;
    1532             : #else
    1533             :       errno = EINVAL;
    1534             : #endif
    1535           0 :       file_error (filename);
    1536           0 :       sh_exit (EX_NOINPUT);
    1537             :     }
    1538             : 
    1539             : #if defined (ARRAY_VARS)
    1540           9 :   GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
    1541           9 :   GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
    1542           9 :   GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
    1543             : 
    1544           9 :   array_push (bash_source_a, filename);
    1545           9 :   if (bash_lineno_a)
    1546             :     {
    1547           9 :       t = itos (executing_line_number ());
    1548           9 :       array_push (bash_lineno_a, t);
    1549           9 :       free (t);
    1550             :     }
    1551           9 :   array_push (funcname_a, "main");
    1552             : #endif
    1553             : 
    1554             : #ifdef HAVE_DEV_FD
    1555           9 :   fd_is_tty = isatty (fd);
    1556             : #else
    1557             :   fd_is_tty = 0;
    1558             : #endif
    1559             : 
    1560             :   /* Only do this with non-tty file descriptors we can seek on. */
    1561           9 :   if (fd_is_tty == 0 && (lseek (fd, 0L, 1) != -1))
    1562             :     {
    1563             :       /* Check to see if the `file' in `bash file' is a binary file
    1564             :          according to the same tests done by execute_simple_command (),
    1565             :          and report an error and exit if it is. */
    1566           9 :       sample_len = read (fd, sample, sizeof (sample));
    1567           9 :       if (sample_len < 0)
    1568             :         {
    1569           0 :           e = errno;
    1570           0 :           if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
    1571             :             {
    1572             : #if defined (EISDIR)
    1573           0 :               errno = EISDIR;
    1574           0 :               file_error (filename);
    1575             : #else         
    1576             :               internal_error (_("%s: Is a directory"), filename);
    1577             : #endif
    1578             :             }
    1579             :           else
    1580             :             {
    1581           0 :               errno = e;
    1582           0 :               file_error (filename);
    1583             :             }
    1584           0 :           exit (EX_NOEXEC);
    1585             :         }
    1586           9 :       else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
    1587             :         {
    1588           0 :           internal_error (_("%s: cannot execute binary file"), filename);
    1589           0 :           exit (EX_BINARY_FILE);
    1590             :         }
    1591             :       /* Now rewind the file back to the beginning. */
    1592           9 :       lseek (fd, 0L, 0);
    1593             :     }
    1594             : 
    1595             :   /* Open the script.  But try to move the file descriptor to a randomly
    1596             :      large one, in the hopes that any descriptors used by the script will
    1597             :      not match with ours. */
    1598           9 :   fd = move_to_high_fd (fd, 1, -1);
    1599             : 
    1600             : #if defined (BUFFERED_INPUT)
    1601           9 :   default_buffered_input = fd;
    1602           9 :   SET_CLOSE_ON_EXEC (default_buffered_input);
    1603             : #else /* !BUFFERED_INPUT */
    1604             :   default_input = fdopen (fd, "r");
    1605             : 
    1606             :   if (default_input == 0)
    1607             :     {
    1608             :       file_error (filename);
    1609             :       exit (EX_NOTFOUND);
    1610             :     }
    1611             : 
    1612             :   SET_CLOSE_ON_EXEC (fd);
    1613             :   if (fileno (default_input) != fd)
    1614             :     SET_CLOSE_ON_EXEC (fileno (default_input));
    1615             : #endif /* !BUFFERED_INPUT */
    1616             : 
    1617             :   /* Just about the only way for this code to be executed is if something
    1618             :      like `bash -i /dev/stdin' is executed. */
    1619           9 :   if (interactive_shell && fd_is_tty)
    1620             :     {
    1621           0 :       dup2 (fd, 0);
    1622           0 :       close (fd);
    1623           0 :       fd = 0;
    1624             : #if defined (BUFFERED_INPUT)
    1625           0 :       default_buffered_input = 0;
    1626             : #else
    1627             :       fclose (default_input);
    1628             :       default_input = stdin;
    1629             : #endif
    1630             :     }
    1631           9 :   else if (forced_interactive && fd_is_tty == 0)
    1632             :     /* But if a script is called with something like `bash -i scriptname',
    1633             :        we need to do a non-interactive setup here, since we didn't do it
    1634             :        before. */
    1635           0 :     init_interactive_script ();
    1636             : 
    1637           9 :   free (filename);
    1638             : 
    1639           9 :   reading_shell_script = 1;
    1640           9 :   return (fd);
    1641             : }
    1642             : 
    1643             : /* Initialize the input routines for the parser. */
    1644             : static void
    1645     9143300 : set_bash_input ()
    1646             : {
    1647             :   /* Make sure the fd from which we are reading input is not in
    1648             :      no-delay mode. */
    1649             : #if defined (BUFFERED_INPUT)
    1650     9143300 :   if (interactive == 0)
    1651     9143300 :     sh_unset_nodelay_mode (default_buffered_input);
    1652             :   else
    1653             : #endif /* !BUFFERED_INPUT */
    1654           0 :     sh_unset_nodelay_mode (fileno (stdin));
    1655             : 
    1656             :   /* with_input_from_stdin really means `with_input_from_readline' */
    1657     9143300 :   if (interactive && no_line_editing == 0)
    1658           0 :     with_input_from_stdin ();
    1659             : #if defined (BUFFERED_INPUT)
    1660     9143300 :   else if (interactive == 0)
    1661     9143300 :     with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
    1662             : #endif /* BUFFERED_INPUT */
    1663             :   else
    1664           0 :     with_input_from_stream (default_input, dollar_vars[0]);
    1665     9143300 : }
    1666             : 
    1667             : /* Close the current shell script input source and forget about it.  This is
    1668             :    extern so execute_cmd.c:initialize_subshell() can call it.  If CHECK_ZERO
    1669             :    is non-zero, we close default_buffered_input even if it's the standard
    1670             :    input (fd 0). */
    1671             : void
    1672     7059203 : unset_bash_input (check_zero)
    1673             :      int check_zero;
    1674             : {
    1675             : #if defined (BUFFERED_INPUT)
    1676     7059203 :   if ((check_zero && default_buffered_input >= 0) ||
    1677     7059203 :       (check_zero == 0 && default_buffered_input > 0))
    1678             :     {
    1679           0 :       close_buffered_fd (default_buffered_input);
    1680           0 :       default_buffered_input = bash_input.location.buffered_fd = -1;
    1681           0 :       bash_input.type = st_none;                /* XXX */
    1682             :     }
    1683             : #else /* !BUFFERED_INPUT */
    1684             :   if (default_input)
    1685             :     {
    1686             :       fclose (default_input);
    1687             :       default_input = (FILE *)NULL;
    1688             :     }
    1689             : #endif /* !BUFFERED_INPUT */
    1690     7059203 : }
    1691             :       
    1692             : 
    1693             : #if !defined (PROGRAM)
    1694             : #  define PROGRAM "bash"
    1695             : #endif
    1696             : 
    1697             : static void
    1698     9143300 : set_shell_name (argv0)
    1699             :      char *argv0;
    1700             : {
    1701             :   /* Here's a hack.  If the name of this shell is "sh", then don't do
    1702             :      any startup files; just try to be more like /bin/sh. */
    1703     9143300 :   shell_name = argv0 ? base_pathname (argv0) : PROGRAM;
    1704             : 
    1705     9143300 :   if (argv0 && *argv0 == '-')
    1706             :     {
    1707           0 :       if (*shell_name == '-')
    1708           0 :         shell_name++;
    1709           0 :       login_shell = 1;
    1710             :     }
    1711             : 
    1712     9143300 :   if (shell_name[0] == 's' && shell_name[1] == 'h' && (shell_name[2] == '\0' || (shell_name[2] == '4' && shell_name[3] == '\0')))
    1713           0 :     act_like_sh++;
    1714     9143300 :   if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
    1715           0 :     su_shell++;
    1716             : 
    1717     9143300 :   shell_name = argv0 ? argv0 : PROGRAM;
    1718     9143300 :   FREE (dollar_vars[0]);
    1719     9143300 :   dollar_vars[0] = savestring (shell_name);
    1720             : 
    1721             :   /* A program may start an interactive shell with
    1722             :           "execl ("/bin/bash", "-", NULL)".
    1723             :      If so, default the name of this shell to our name. */
    1724     9143300 :   if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1]))
    1725           0 :     shell_name = PROGRAM;
    1726     9143300 : }
    1727             : 
    1728             : static void
    1729             : init_interactive ()
    1730             : {
    1731           0 :   expand_aliases = interactive_shell = startup_state = 1;
    1732           0 :   interactive = 1;
    1733             : #if defined (HISTORY)
    1734           0 :   remember_on_history = enable_history_list = 1;        /* XXX */
    1735             : #endif
    1736             : }
    1737             : 
    1738             : static void
    1739     9143300 : init_noninteractive ()
    1740             : {
    1741             : #if defined (HISTORY)
    1742     9143300 :   bash_history_reinit (0);
    1743             : #endif /* HISTORY */
    1744     9143300 :   interactive_shell = startup_state = interactive = 0;
    1745     9143300 :   expand_aliases = posixly_correct;     /* XXX - was 0 not posixly_correct */
    1746     9143300 :   no_line_editing = 1;
    1747             : #if defined (JOB_CONTROL)
    1748             :   /* Even if the shell is not interactive, enable job control if the -i or
    1749             :      -m option is supplied at startup. */
    1750    18286600 :   set_job_control (forced_interactive||jobs_m_flag);
    1751             : #endif /* JOB_CONTROL */
    1752     9143300 : }
    1753             : 
    1754             : static void
    1755             : init_interactive_script ()
    1756             : {
    1757           0 :   init_noninteractive ();
    1758           0 :   expand_aliases = interactive_shell = startup_state = 1;
    1759             : #if defined (HISTORY)
    1760           0 :   remember_on_history = enable_history_list = 1;        /* XXX */
    1761             : #endif
    1762             : }
    1763             : 
    1764             : void
    1765           0 : get_current_user_info ()
    1766             : {
    1767           0 :   struct passwd *entry;
    1768             : 
    1769             :   /* Don't fetch this more than once. */
    1770           0 :   if (current_user.user_name == 0)
    1771             :     {
    1772             : #if defined (__TANDEM)
    1773             :       entry = getpwnam (getlogin ());
    1774             : #else
    1775           0 :       entry = getpwuid (current_user.uid);
    1776             : #endif
    1777           0 :       if (entry)
    1778             :         {
    1779           0 :           current_user.user_name = savestring (entry->pw_name);
    1780           0 :           current_user.shell = (entry->pw_shell && entry->pw_shell[0])
    1781           0 :                                 ? savestring (entry->pw_shell)
    1782           0 :                                 : savestring ("/bin/sh");
    1783           0 :           current_user.home_dir = savestring (entry->pw_dir);
    1784             :         }
    1785             :       else
    1786             :         {
    1787           0 :           current_user.user_name = _("I have no name!");
    1788           0 :           current_user.user_name = savestring (current_user.user_name);
    1789           0 :           current_user.shell = savestring ("/bin/sh");
    1790           0 :           current_user.home_dir = savestring ("/");
    1791             :         }
    1792             : #if defined (HAVE_GETPWENT)
    1793           0 :       endpwent ();
    1794             : #endif
    1795             :     }
    1796           0 : }
    1797             : 
    1798             : /* Do whatever is necessary to initialize the shell.
    1799             :    Put new initializations in here. */
    1800             : static void
    1801     9143300 : shell_initialize ()
    1802             : {
    1803     9143300 :   char hostname[256];
    1804             : #if defined (RESTRICTED_SHELL)
    1805     9143300 :   int should_be_restricted;
    1806             : #endif
    1807             : 
    1808             :   /* Line buffer output for stderr and stdout. */
    1809     9143300 :   if (shell_initialized == 0)
    1810             :     {
    1811     9143291 :       sh_setlinebuf (stderr);
    1812     9143291 :       sh_setlinebuf (stdout);
    1813             :     }
    1814             : 
    1815             :   /* Sort the array of shell builtins so that the binary search in
    1816             :      find_shell_builtin () works correctly. */
    1817     9143300 :   initialize_shell_builtins ();
    1818             : 
    1819             :   /* Initialize the trap signal handlers before installing our own
    1820             :      signal handlers.  traps.c:restore_original_signals () is responsible
    1821             :      for restoring the original default signal handlers.  That function
    1822             :      is called when we make a new child. */
    1823     9143300 :   initialize_traps ();
    1824     9143300 :   initialize_signals (0);
    1825             : 
    1826             :   /* It's highly unlikely that this will change. */
    1827     9143300 :   if (current_host_name == 0)
    1828             :     {
    1829             :       /* Initialize current_host_name. */
    1830     9143291 :       if (gethostname (hostname, 255) < 0)
    1831           0 :         current_host_name = "??host??";
    1832             :       else
    1833     9143291 :         current_host_name = savestring (hostname);
    1834             :     }
    1835             : 
    1836             :   /* Initialize the stuff in current_user that comes from the password
    1837             :      file.  We don't need to do this right away if the shell is not
    1838             :      interactive. */
    1839     9143300 :   if (interactive_shell)
    1840           0 :     get_current_user_info ();
    1841             : 
    1842             :   /* Initialize our interface to the tilde expander. */
    1843     9143300 :   tilde_initialize ();
    1844             : 
    1845             : #if defined (RESTRICTED_SHELL)
    1846     9143300 :   should_be_restricted = shell_is_restricted (shell_name);
    1847             : #endif
    1848             : 
    1849             :   /* Initialize internal and environment variables.  Don't import shell
    1850             :      functions from the environment if we are running in privileged or
    1851             :      restricted mode or if the shell is running setuid. */
    1852             : #if defined (RESTRICTED_SHELL)
    1853    18286600 :   initialize_shell_variables (shell_environment, privileged_mode||restricted||should_be_restricted||running_setuid);
    1854             : #else
    1855             :   initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
    1856             : #endif
    1857             : 
    1858             :   /* Initialize the data structures for storing and running jobs. */
    1859     9143300 :   initialize_job_control (jobs_m_flag);
    1860             : 
    1861             :   /* Initialize input streams to null. */
    1862     9143300 :   initialize_bash_input ();
    1863             : 
    1864     9143300 :   initialize_flags ();
    1865             : 
    1866             :   /* Initialize the shell options.  Don't import the shell options
    1867             :      from the environment variables $SHELLOPTS or $BASHOPTS if we are
    1868             :      running in privileged or restricted mode or if the shell is running
    1869             :      setuid. */
    1870             : #if defined (RESTRICTED_SHELL)
    1871    18286600 :   initialize_shell_options (privileged_mode||restricted||should_be_restricted||running_setuid);
    1872    18286600 :   initialize_bashopts (privileged_mode||restricted||should_be_restricted||running_setuid);
    1873             : #else
    1874             :   initialize_shell_options (privileged_mode||running_setuid);
    1875             :   initialize_bashopts (privileged_mode||running_setuid);
    1876             : #endif
    1877     9143300 : }
    1878             : 
    1879             : /* Function called by main () when it appears that the shell has already
    1880             :    had some initialization performed.  This is supposed to reset the world
    1881             :    back to a pristine state, as if we had been exec'ed. */
    1882             : static void
    1883           9 : shell_reinitialize ()
    1884             : {
    1885             :   /* The default shell prompts. */
    1886           9 :   primary_prompt = PPROMPT;
    1887           9 :   secondary_prompt = SPROMPT;
    1888             : 
    1889             :   /* Things that get 1. */
    1890           9 :   current_command_number = 1;
    1891             : 
    1892             :   /* We have decided that the ~/.bashrc file should not be executed
    1893             :      for the invocation of each shell script.  If the variable $ENV
    1894             :      (or $BASH_ENV) is set, its value is used as the name of a file
    1895             :      to source. */
    1896           9 :   no_rc = no_profile = 1;
    1897             : 
    1898             :   /* Things that get 0. */
    1899           9 :   login_shell = make_login_shell = interactive = executing = 0;
    1900           9 :   debugging = do_version = line_number = last_command_exit_value = 0;
    1901           9 :   forced_interactive = interactive_shell = 0;
    1902           9 :   subshell_environment = running_in_background = 0;
    1903           9 :   expand_aliases = 0;
    1904             : 
    1905             :   /* XXX - should we set jobs_m_flag to 0 here? */
    1906             : 
    1907             : #if defined (HISTORY)
    1908           9 :   bash_history_reinit (enable_history_list = 0);
    1909             : #endif /* HISTORY */
    1910             : 
    1911             : #if defined (RESTRICTED_SHELL)
    1912           9 :   restricted = 0;
    1913             : #endif /* RESTRICTED_SHELL */
    1914             : 
    1915             :   /* Ensure that the default startup file is used.  (Except that we don't
    1916             :      execute this file for reinitialized shells). */
    1917           9 :   bashrc_file = DEFAULT_BASHRC;
    1918             : 
    1919             :   /* Delete all variables and functions.  They will be reinitialized when
    1920             :      the environment is parsed. */
    1921           9 :   delete_all_contexts (shell_variables);
    1922           9 :   delete_all_variables (shell_functions);
    1923             : 
    1924           9 :   reinit_special_variables ();
    1925             : 
    1926             : #if defined (READLINE)
    1927           9 :   bashline_reinitialize ();
    1928             : #endif
    1929             : 
    1930           9 :   shell_reinitialized = 1;
    1931           9 : }
    1932             : 
    1933             : static void
    1934           0 : show_shell_usage (fp, extra)
    1935             :      FILE *fp;
    1936             :      int extra;
    1937             : {
    1938           0 :   int i;
    1939           0 :   char *set_opts, *s, *t;
    1940             : 
    1941           0 :   if (extra)
    1942           0 :     fprintf (fp, _("GNU bash, version %s-(%s)\n"), shell_version_string (), MACHTYPE);
    1943           0 :   fprintf (fp, _("Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n"),
    1944             :              shell_name, shell_name);
    1945           0 :   fputs (_("GNU long options:\n"), fp);
    1946           0 :   for (i = 0; long_args[i].name; i++)
    1947           0 :     fprintf (fp, "\t--%s\n", long_args[i].name);
    1948             : 
    1949           0 :   fputs (_("Shell options:\n"), fp);
    1950           0 :   fputs (_("\t-ilrsD or -c command or -O shopt_option\t\t(invocation only)\n"), fp);
    1951             : 
    1952           0 :   for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
    1953           0 :     if (STREQ (shell_builtins[i].name, "set"))
    1954           0 :       set_opts = savestring (shell_builtins[i].short_doc);
    1955           0 :   if (set_opts)
    1956             :     {
    1957           0 :       s = strchr (set_opts, '[');
    1958           0 :       if (s == 0)
    1959           0 :         s = set_opts;
    1960           0 :       while (*++s == '-')
    1961           0 :         ;
    1962           0 :       t = strchr (s, ']');
    1963           0 :       if (t)
    1964           0 :         *t = '\0';
    1965           0 :       fprintf (fp, _("\t-%s or -o option\n"), s);
    1966           0 :       free (set_opts);
    1967             :     }
    1968             : 
    1969           0 :   if (extra)
    1970             :     {
    1971           0 :       fprintf (fp, _("Type `%s -c \"help set\"' for more information about shell options.\n"), shell_name);
    1972           0 :       fprintf (fp, _("Type `%s -c help' for more information about shell builtin commands.\n"), shell_name);
    1973           0 :       fprintf (fp, _("Use the `bashbug' command to report bugs.\n"));
    1974           0 :       fprintf (fp, "\n");
    1975           0 :       fprintf (fp, _("bash home page: <http://www.gnu.org/software/bash>\n"));
    1976           0 :       fprintf (fp, _("General help using GNU software: <http://www.gnu.org/gethelp/>\n"));
    1977             :     }
    1978           0 : }
    1979             : 
    1980             : static void
    1981           0 : add_shopt_to_alist (opt, on_or_off)
    1982             :      char *opt;
    1983             :      int on_or_off;
    1984             : {
    1985           0 :   if (shopt_ind >= shopt_len)
    1986             :     {
    1987           0 :       shopt_len += 8;
    1988           0 :       shopt_alist = (STRING_INT_ALIST *)xrealloc (shopt_alist, shopt_len * sizeof (shopt_alist[0]));
    1989             :     }
    1990           0 :   shopt_alist[shopt_ind].word = opt;
    1991           0 :   shopt_alist[shopt_ind].token = on_or_off;
    1992           0 :   shopt_ind++;
    1993           0 : }
    1994             : 
    1995             : static void
    1996           0 : run_shopt_alist ()
    1997             : {
    1998           0 :   register int i;
    1999             : 
    2000           0 :   for (i = 0; i < shopt_ind; i++)
    2001           0 :     if (shopt_setopt (shopt_alist[i].word, (shopt_alist[i].token == '-')) != EXECUTION_SUCCESS)
    2002           0 :       exit (EX_BADUSAGE);
    2003           0 :   free (shopt_alist);
    2004           0 :   shopt_alist = 0;
    2005           0 :   shopt_ind = shopt_len = 0;
    2006           0 : }

Generated by: LCOV version 1.14.0.6.4058