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

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