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