source: trunk/third/bash/shell.c @ 21276

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