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

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