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