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