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