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