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