blob: ee9d445d20cc0eae807800a92ecab96045262300 [file] [log] [blame]
Jari Aaltobb706242000-03-17 21:46:59 +00001/* shell.c -- GNU's idea of the POSIX shell specification. */
Jari Aalto726f6381996-08-26 18:22:31 +00002
Chet Ramey74091dd2022-09-26 11:49:46 -04003/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
Jari Aaltobb706242000-03-17 21:46:59 +00005 This file is part of GNU Bash, the Bourne Again SHell.
Jari Aalto726f6381996-08-26 18:22:31 +00006
Jari Aalto31859422009-01-12 13:36:28 +00007 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.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 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.
Jari Aalto726f6381996-08-26 18:22:31 +000016
Jari Aaltobb706242000-03-17 21:46:59 +000017 You should have received a copy of the GNU General Public License
Jari Aalto31859422009-01-12 13:36:28 +000018 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aalto31859422009-01-12 13:36:28 +000021/*
Jari Aalto726f6381996-08-26 18:22:31 +000022 Birthdate:
23 Sunday, January 10th, 1988.
24 Initial author: Brian Fox
25*/
26#define INSTALL_DEBUG_MODE
27
Jari Aaltoccc6cda1996-12-23 17:02:34 +000028#include "config.h"
29
Jari Aalto726f6381996-08-26 18:22:31 +000030#include "bashtypes.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000031#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000032# include <sys/file.h>
33#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000034#include "posixstat.h"
Jari Aaltof73dda02001-11-13 17:56:06 +000035#include "posixtime.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000036#include "bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000037#include <stdio.h>
38#include <signal.h>
39#include <errno.h>
Jari Aalto726f6381996-08-26 18:22:31 +000040#include "filecntl.h"
Chet Rameya0c0a002016-09-15 16:59:08 -040041#if defined (HAVE_PWD_H)
42# include <pwd.h>
43#endif
Jari Aalto726f6381996-08-26 18:22:31 +000044
Jari Aaltoccc6cda1996-12-23 17:02:34 +000045#if defined (HAVE_UNISTD_H)
46# include <unistd.h>
Jari Aalto726f6381996-08-26 18:22:31 +000047#endif
48
Jari Aaltob80f6442004-07-27 13:29:18 +000049#include "bashintl.h"
50
Jari Aaltof73dda02001-11-13 17:56:06 +000051#define NEED_SH_SETLINEBUF_DECL /* used in externs.h */
52
Jari Aalto726f6381996-08-26 18:22:31 +000053#include "shell.h"
Chet Rameyd233b482019-01-07 09:27:52 -050054#include "parser.h"
Jari Aalto726f6381996-08-26 18:22:31 +000055#include "flags.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000056#include "trap.h"
57#include "mailcheck.h"
58#include "builtins.h"
59#include "builtins/common.h"
Jari Aalto726f6381996-08-26 18:22:31 +000060
61#if defined (JOB_CONTROL)
62#include "jobs.h"
Chet Rameya0c0a002016-09-15 16:59:08 -040063#else
Chet Rameyd233b482019-01-07 09:27:52 -050064extern int running_in_background;
Chet Ramey8868eda2020-12-06 15:51:17 -050065extern int initialize_job_control PARAMS((int));
66extern int get_tty_state PARAMS((void));
Jari Aalto726f6381996-08-26 18:22:31 +000067#endif /* JOB_CONTROL */
68
69#include "input.h"
70#include "execute_cmd.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000071#include "findcmd.h"
Jari Aalto726f6381996-08-26 18:22:31 +000072
Jari Aalto7117c2d2002-07-17 14:10:11 +000073#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
74# include <malloc/shmalloc.h>
Chet Ramey74091dd2022-09-26 11:49:46 -040075#elif defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC)
76# include <malloc/shmalloc.h>
Jari Aalto7117c2d2002-07-17 14:10:11 +000077#endif
78
Jari Aalto726f6381996-08-26 18:22:31 +000079#if defined (HISTORY)
80# include "bashhist.h"
81# include <readline/history.h>
82#endif
83
Jari Aalto31859422009-01-12 13:36:28 +000084#if defined (READLINE)
Chet Ramey84c617e2015-01-15 10:21:08 -050085# include <readline/readline.h>
Jari Aalto31859422009-01-12 13:36:28 +000086# include "bashline.h"
87#endif
88
Jari Aalto726f6381996-08-26 18:22:31 +000089#include <tilde/tilde.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000090#include <glob/strmatch.h>
Jari Aalto726f6381996-08-26 18:22:31 +000091
Jari Aaltob72432f1999-02-19 17:11:39 +000092#if defined (__OPENNT)
93# include <opennt/opennt.h>
94#endif
95
Jari Aaltoccc6cda1996-12-23 17:02:34 +000096#if !defined (HAVE_GETPW_DECLS)
Jari Aalto726f6381996-08-26 18:22:31 +000097extern struct passwd *getpwuid ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +000098#endif /* !HAVE_GETPW_DECLS */
Jari Aalto726f6381996-08-26 18:22:31 +000099
Jari Aalto726f6381996-08-26 18:22:31 +0000100#if !defined (errno)
101extern int errno;
102#endif
103
Jari Aaltob72432f1999-02-19 17:11:39 +0000104#if defined (NO_MAIN_ENV_ARG)
105extern char **environ; /* used if no third argument to main() */
106#endif
107
Jari Aalto95732b42005-12-07 14:08:12 +0000108extern int gnu_error_format;
Jari Aalto726f6381996-08-26 18:22:31 +0000109
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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000112int shell_initialized = 0;
Chet Rameyd233b482019-01-07 09:27:52 -0500113int bash_argv_initialized = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000114
115COMMAND *global_command = (COMMAND *)NULL;
116
Jari Aalto726f6381996-08-26 18:22:31 +0000117/* Information about the current user. */
118struct user_info current_user =
119{
Jari Aaltof73dda02001-11-13 17:56:06 +0000120 (uid_t)-1, (uid_t)-1, (gid_t)-1, (gid_t)-1,
121 (char *)NULL, (char *)NULL, (char *)NULL
Jari Aalto726f6381996-08-26 18:22:31 +0000122};
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)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000131 -1 = login shell from "--login" (or -l) flag.
Jari Aalto726f6381996-08-26 18:22:31 +0000132 -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
Jari Aaltocce855b1998-04-17 19:52:44 +0000144/* Non-zero means to send a SIGHUP to all jobs when an interactive login
145 shell exits. */
146int hup_on_exit = 0;
147
Jari Aalto31859422009-01-12 13:36:28 +0000148/* 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
Jari Aalto726f6381996-08-26 18:22:31 +0000154/* Tells what state the shell was in when it started:
155 0 = non-interactive shell script
156 1 = interactive
157 2 = -c command
Jari Aalto7117c2d2002-07-17 14:10:11 +0000158 3 = wordexp evaluation
Jari Aalto726f6381996-08-26 18:22:31 +0000159 This is a superset of the information provided by interactive_shell.
160*/
161int startup_state = 0;
Chet Rameya0c0a002016-09-15 16:59:08 -0400162int reading_shell_script = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000163
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
Jari Aalto726f6381996-08-26 18:22:31 +0000176/* Non-zero is the recursion depth for commands. */
177int indirection_level = 0;
178
Jari Aalto726f6381996-08-26 18:22:31 +0000179/* 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;
Chet Ramey8868eda2020-12-06 15:51:17 -0500184struct timeval shellstart;
Jari Aalto726f6381996-08-26 18:22:31 +0000185
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000186/* Are we running in an emacs shell window? */
187int running_under_emacs;
188
Jari Aalto31859422009-01-12 13:36:28 +0000189/* 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
Jari Aalto726f6381996-08-26 18:22:31 +0000196/* The name of the .(shell)rc file. */
Chet Rameya0c0a002016-09-15 16:59:08 -0400197static char *bashrc_file = DEFAULT_BASHRC;
Jari Aalto726f6381996-08-26 18:22:31 +0000198
199/* Non-zero means to act more like the Bourne shell on startup. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000200static 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;
Jari Aalto726f6381996-08-26 18:22:31 +0000210
211/* Values for the long-winded argument names. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000212static 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 */
Jari Aalto726f6381996-08-26 18:22:31 +0000218
Jari Aaltob80f6442004-07-27 13:29:18 +0000219int debugging_mode = 0; /* In debugging mode with --debugger */
Chet Rameyac50fba2014-02-26 09:36:43 -0500220#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
Chet Ramey74091dd2022-09-26 11:49:46 -0400225#if defined (TRANSLATABLE_STRINGS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000226int dump_translatable_strings; /* Dump strings in $"...", don't execute. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000227int dump_po_strings; /* Dump strings in $"..." in po format */
Chet Ramey74091dd2022-09-26 11:49:46 -0400228#endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000229int wordexp_only = 0; /* Do word expansion only */
Jari Aaltob80f6442004-07-27 13:29:18 +0000230int protected_mode = 0; /* No command substitution with --wordexp */
Jari Aalto726f6381996-08-26 18:22:31 +0000231
Chet Rameyd233b482019-01-07 09:27:52 -0500232int pretty_print_mode = 0; /* pretty-print a shell script */
233
Jari Aalto95732b42005-12-07 14:08:12 +0000234#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
Jari Aalto726f6381996-08-26 18:22:31 +0000240/* Some long-winded argument names. These are obviously new. */
241#define Int 1
242#define Charp 2
Jari Aalto31859422009-01-12 13:36:28 +0000243static const struct {
244 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +0000245 int type;
246 int *int_value;
247 char **char_value;
248} long_args[] = {
249 { "debug", Int, &debugging, (char **)0x0 },
Jari Aaltob80f6442004-07-27 13:29:18 +0000250#if defined (DEBUGGER)
251 { "debugger", Int, &debugging_mode, (char **)0x0 },
252#endif
Chet Ramey74091dd2022-09-26 11:49:46 -0400253#if defined (TRANSLATABLE_STRINGS)
Jari Aaltocce855b1998-04-17 19:52:44 +0000254 { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 },
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000255 { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 },
Chet Ramey74091dd2022-09-26 11:49:46 -0400256#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000257 { "help", Int, &want_initial_help, (char **)0x0 },
Jari Aalto28ef6c32001-04-06 19:14:31 +0000258 { "init-file", Charp, (int *)0x0, &bashrc_file },
Jari Aalto726f6381996-08-26 18:22:31 +0000259 { "login", Int, &make_login_shell, (char **)0x0 },
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000260 { "noediting", Int, &no_line_editing, (char **)0x0 },
261 { "noprofile", Int, &no_profile, (char **)0x0 },
262 { "norc", Int, &no_rc, (char **)0x0 },
Jari Aalto726f6381996-08-26 18:22:31 +0000263 { "posix", Int, &posixly_correct, (char **)0x0 },
Chet Rameyd233b482019-01-07 09:27:52 -0500264 { "pretty-print", Int, &pretty_print_mode, (char **)0x0 },
Chet Rameyac50fba2014-02-26 09:36:43 -0500265#if defined (WORDEXP_OPTION)
Jari Aaltob80f6442004-07-27 13:29:18 +0000266 { "protected", Int, &protected_mode, (char **)0x0 },
Chet Rameyac50fba2014-02-26 09:36:43 -0500267#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000268 { "rcfile", Charp, (int *)0x0, &bashrc_file },
269#if defined (RESTRICTED_SHELL)
270 { "restricted", Int, &restricted, (char **)0x0 },
271#endif
Chet Rameya0c0a002016-09-15 16:59:08 -0400272 { "verbose", Int, &verbose_flag, (char **)0x0 },
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000273 { "version", Int, &do_version, (char **)0x0 },
Chet Ramey00018032011-11-21 20:51:19 -0500274#if defined (WORDEXP_OPTION)
Jari Aaltocce855b1998-04-17 19:52:44 +0000275 { "wordexp", Int, &wordexp_only, (char **)0x0 },
Chet Ramey00018032011-11-21 20:51:19 -0500276#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000277 { (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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000284procenv_t subshell_top_level;
Jari Aalto726f6381996-08-26 18:22:31 +0000285int subshell_argc;
286char **subshell_argv;
287char **subshell_envp;
288
Chet Ramey495aee42011-11-22 19:11:26 -0500289char *exec_argv0;
290
Jari Aalto726f6381996-08-26 18:22:31 +0000291#if defined (BUFFERED_INPUT)
292/* The file descriptor from which the shell is reading input. */
293int default_buffered_input = -1;
294#endif
295
Jari Aaltobb706242000-03-17 21:46:59 +0000296/* 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
Jari Aaltob80f6442004-07-27 13:29:18 +0000300/* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */
301char *command_execution_string; /* argument to -c option */
Chet Rameyd233b482019-01-07 09:27:52 -0500302char *shell_script_filename; /* shell script */
Jari Aaltob80f6442004-07-27 13:29:18 +0000303
Jari Aalto7117c2d2002-07-17 14:10:11 +0000304int malloc_trace_at_exit = 0;
305
Jari Aalto28ef6c32001-04-06 19:14:31 +0000306static int shell_reinitialized = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000307
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000308static FILE *default_input;
Jari Aalto726f6381996-08-26 18:22:31 +0000309
Jari Aaltof73dda02001-11-13 17:56:06 +0000310static STRING_INT_ALIST *shopt_alist;
311static int shopt_ind = 0, shopt_len = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000312
Chet Ramey8868eda2020-12-06 15:51:17 -0500313static 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));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000316
Chet Ramey8868eda2020-12-06 15:51:17 -0500317static void start_debugger PARAMS((void));
Jari Aaltob80f6442004-07-27 13:29:18 +0000318
Chet Ramey8868eda2020-12-06 15:51:17 -0500319static void add_shopt_to_alist PARAMS((char *, int));
320static void run_shopt_alist PARAMS((void));
Jari Aalto726f6381996-08-26 18:22:31 +0000321
Chet Ramey8868eda2020-12-06 15:51:17 -0500322static 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 *));
Chet Ramey00018032011-11-21 20:51:19 -0500327#if defined (WORDEXP_OPTION)
Chet Ramey8868eda2020-12-06 15:51:17 -0500328static int run_wordexp PARAMS((char *));
Chet Ramey00018032011-11-21 20:51:19 -0500329#endif
Jari Aaltof73dda02001-11-13 17:56:06 +0000330
Chet Ramey8868eda2020-12-06 15:51:17 -0500331static int uidget PARAMS((void));
Jari Aaltof73dda02001-11-13 17:56:06 +0000332
Chet Ramey8868eda2020-12-06 15:51:17 -0500333static void set_option_defaults PARAMS((void));
334static void reset_option_defaults PARAMS((void));
Jari Aaltof73dda02001-11-13 17:56:06 +0000335
Chet Ramey8868eda2020-12-06 15:51:17 -0500336static void init_interactive PARAMS((void));
337static void init_noninteractive PARAMS((void));
338static void init_interactive_script PARAMS((void));
Jari Aaltof73dda02001-11-13 17:56:06 +0000339
Chet Ramey8868eda2020-12-06 15:51:17 -0500340static 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));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000345
Jari Aalto28ef6c32001-04-06 19:14:31 +0000346#ifdef __CYGWIN__
Jari Aaltocce855b1998-04-17 19:52:44 +0000347static void
348_cygwin32_check_tmp ()
349{
350 struct stat sb;
351
352 if (stat ("/tmp", &sb) < 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000353 internal_warning (_("could not find /tmp, please create!"));
Jari Aaltocce855b1998-04-17 19:52:44 +0000354 else
355 {
356 if (S_ISDIR (sb.st_mode) == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000357 internal_warning (_("/tmp must be a valid directory name"));
Jari Aaltocce855b1998-04-17 19:52:44 +0000358 }
359}
Jari Aalto28ef6c32001-04-06 19:14:31 +0000360#endif /* __CYGWIN__ */
Jari Aaltocce855b1998-04-17 19:52:44 +0000361
Jari Aaltob72432f1999-02-19 17:11:39 +0000362#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 */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000369int
Jari Aalto726f6381996-08-26 18:22:31 +0000370main (argc, argv, env)
371 int argc;
372 char **argv, **env;
Jari Aaltob72432f1999-02-19 17:11:39 +0000373#endif /* !NO_MAIN_ENV_ARG */
Jari Aalto726f6381996-08-26 18:22:31 +0000374{
375 register int i;
Jari Aaltof73dda02001-11-13 17:56:06 +0000376 int code, old_errexit_flag;
377#if defined (RESTRICTED_SHELL)
378 int saverst;
379#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000380 volatile int locally_skip_execution;
381 volatile int arg_index, top_level_arg_index;
Jari Aaltob72432f1999-02-19 17:11:39 +0000382#ifdef __OPENNT
383 char **env;
384
385 env = environ;
386#endif /* __OPENNT */
Jari Aalto726f6381996-08-26 18:22:31 +0000387
Jari Aaltof73dda02001-11-13 17:56:06 +0000388 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000397 /* Catch early SIGINTs. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500398 code = setjmp_nosigs (top_level);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000399 if (code)
400 exit (2);
Jari Aalto726f6381996-08-26 18:22:31 +0000401
Chet Ramey00018032011-11-21 20:51:19 -0500402 xtrace_init ();
403
Jari Aalto7117c2d2002-07-17 14:10:11 +0000404#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
Chet Rameya0c0a002016-09-15 16:59:08 -0400405 malloc_set_register (1); /* XXX - change to 1 for malloc debugging */
Jari Aaltof73dda02001-11-13 17:56:06 +0000406#endif
407
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000408 check_dev_tty ();
Jari Aalto726f6381996-08-26 18:22:31 +0000409
Jari Aalto28ef6c32001-04-06 19:14:31 +0000410#ifdef __CYGWIN__
Jari Aaltocce855b1998-04-17 19:52:44 +0000411 _cygwin32_check_tmp ();
Jari Aalto28ef6c32001-04-06 19:14:31 +0000412#endif /* __CYGWIN__ */
Jari Aaltocce855b1998-04-17 19:52:44 +0000413
Jari Aalto726f6381996-08-26 18:22:31 +0000414 /* Wait forever if we are debugging a login shell. */
Jari Aalto95732b42005-12-07 14:08:12 +0000415 while (debugging_login_shell) sleep (3);
Jari Aalto726f6381996-08-26 18:22:31 +0000416
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000417 set_default_locale ();
Jari Aalto726f6381996-08-26 18:22:31 +0000418
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000419 running_setuid = uidget ();
Jari Aalto726f6381996-08-26 18:22:31 +0000420
Jari Aalto28ef6c32001-04-06 19:14:31 +0000421 if (getenv ("POSIXLY_CORRECT") || getenv ("POSIX_PEDANTIC"))
422 posixly_correct = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000423
424#if defined (USE_GNU_MALLOC_LIBRARY)
425 mcheck (programming_error, (void (*) ())0);
426#endif /* USE_GNU_MALLOC_LIBRARY */
427
Chet Rameya0c0a002016-09-15 16:59:08 -0400428 if (setjmp_sigs (subshell_top_level))
Jari Aalto726f6381996-08-26 18:22:31 +0000429 {
430 argc = subshell_argc;
431 argv = subshell_argv;
432 env = subshell_envp;
433 sourced_env = 0;
434 }
435
Jari Aalto28ef6c32001-04-06 19:14:31 +0000436 shell_reinitialized = 0;
437
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000438 /* Initialize `local' variables for all `invocations' of main (). */
Jari Aalto726f6381996-08-26 18:22:31 +0000439 arg_index = 1;
Jari Aalto95732b42005-12-07 14:08:12 +0000440 if (arg_index > argc)
441 arg_index = argc;
Chet Rameyd233b482019-01-07 09:27:52 -0500442 command_execution_string = shell_script_filename = (char *)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000443 want_pending_command = locally_skip_execution = read_from_stdin = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000444 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 ();
Chet Rameyac50fba2014-02-26 09:36:43 -0500462 if (setjmp_nosigs (top_level))
Jari Aalto726f6381996-08-26 18:22:31 +0000463 exit (2);
464 }
465
Jari Aalto726f6381996-08-26 18:22:31 +0000466 shell_environment = env;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000467 set_shell_name (argv[0]);
Chet Ramey8868eda2020-12-06 15:51:17 -0500468
469 gettimeofday (&shellstart, 0);
470 shell_start_time = shellstart.tv_sec;
Jari Aalto726f6381996-08-26 18:22:31 +0000471
Jari Aalto726f6381996-08-26 18:22:31 +0000472 /* Parse argument flags from the input line. */
473
474 /* Find full word arguments first. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000475 arg_index = parse_long_options (argv, arg_index, argc);
Chet Rameya0c0a002016-09-15 16:59:08 -0400476
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000477 if (want_initial_help)
Jari Aalto726f6381996-08-26 18:22:31 +0000478 {
Jari Aaltod166f041997-06-05 14:59:13 +0000479 show_shell_usage (stdout, 1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000480 exit (EXECUTION_SUCCESS);
Jari Aalto726f6381996-08-26 18:22:31 +0000481 }
482
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000483 if (do_version)
484 {
485 show_shell_version (1);
486 exit (EXECUTION_SUCCESS);
487 }
Jari Aalto726f6381996-08-26 18:22:31 +0000488
Chet Rameya0c0a002016-09-15 16:59:08 -0400489 echo_input_at_read = verbose_flag; /* --verbose given */
490
Jari Aalto7117c2d2002-07-17 14:10:11 +0000491 /* 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. */
Jari Aalto726f6381996-08-26 18:22:31 +0000497 if (make_login_shell)
498 {
499 login_shell++;
500 login_shell = -login_shell;
501 }
502
Chet Ramey00018032011-11-21 20:51:19 -0500503 set_login_shell ("login_shell", login_shell != 0);
Jari Aaltof73dda02001-11-13 17:56:06 +0000504
Chet Ramey74091dd2022-09-26 11:49:46 -0400505#if defined (TRANSLATABLE_STRINGS)
Jari Aaltocce855b1998-04-17 19:52:44 +0000506 if (dump_po_strings)
507 dump_translatable_strings = 1;
508
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000509 if (dump_translatable_strings)
510 read_but_dont_execute = 1;
Chet Ramey74091dd2022-09-26 11:49:46 -0400511#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000512
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000513 if (running_setuid && privileged_mode == 0)
514 disable_priv_mode ();
Jari Aalto726f6381996-08-26 18:22:31 +0000515
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 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000521 command_execution_string = argv[arg_index];
522 if (command_execution_string == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000523 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000524 report_error (_("%s: option requires an argument"), "-c");
525 exit (EX_BADUSAGE);
Jari Aalto726f6381996-08-26 18:22:31 +0000526 }
527 arg_index++;
528 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000529 this_command_name = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000530
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
Jari Aaltob80f6442004-07-27 13:29:18 +0000537 standard error is a terminal
Jari Aalto726f6381996-08-26 18:22:31 +0000538 Refer to Posix.2, the description of the `sh' utility. */
539
540 if (forced_interactive || /* -i flag */
Jari Aaltob80f6442004-07-27 13:29:18 +0000541 (!command_execution_string && /* No -c command and ... */
Jari Aaltocce855b1998-04-17 19:52:44 +0000542 wordexp_only == 0 && /* No --wordexp and ... */
Jari Aalto726f6381996-08-26 18:22:31 +0000543 ((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 */
Jari Aaltob80f6442004-07-27 13:29:18 +0000546 isatty (fileno (stderr)))) /* error output is a terminal. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000547 init_interactive ();
Jari Aalto726f6381996-08-26 18:22:31 +0000548 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000549 init_noninteractive ();
Jari Aalto726f6381996-08-26 18:22:31 +0000550
Jari Aalto726f6381996-08-26 18:22:31 +0000551 /*
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
Chet Ramey495aee42011-11-22 19:11:26 -0500556 * 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.
Jari Aalto726f6381996-08-26 18:22:31 +0000559 */
560 if (login_shell && interactive_shell)
561 {
562 for (i = 3; i < 20; i++)
Chet Ramey495aee42011-11-22 19:11:26 -0500563 SET_CLOSE_ON_EXEC (i);
Jari Aalto726f6381996-08-26 18:22:31 +0000564 }
Jari Aalto726f6381996-08-26 18:22:31 +0000565
Jari Aalto7117c2d2002-07-17 14:10:11 +0000566 /* 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. */
Jari Aaltod166f041997-06-05 14:59:13 +0000568 if (posixly_correct)
569 {
Jari Aalto95732b42005-12-07 14:08:12 +0000570 bind_variable ("POSIXLY_CORRECT", "y", 0);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000571 sv_strict_posix ("POSIXLY_CORRECT");
Jari Aaltod166f041997-06-05 14:59:13 +0000572 }
573
Jari Aaltof73dda02001-11-13 17:56:06 +0000574 /* Now we run the shopt_alist and process the options. */
575 if (shopt_alist)
576 run_shopt_alist ();
577
Jari Aalto726f6381996-08-26 18:22:31 +0000578 /* 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
Jari Aalto06285672006-10-10 14:15:34 +0000582 set_default_lang ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000583 set_default_locale_vars ();
584
Jari Aalto31859422009-01-12 13:36:28 +0000585 /*
Chet Rameya0c0a002016-09-15 16:59:08 -0400586 * 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)
Jari Aalto31859422009-01-12 13:36:28 +0000594 */
Jari Aalto726f6381996-08-26 18:22:31 +0000595 if (interactive_shell)
596 {
Chet Rameyd233b482019-01-07 09:27:52 -0500597 char *term, *emacs, *inside_emacs;
Chet Rameya0c0a002016-09-15 16:59:08 -0400598 int emacs_term, in_emacs;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000599
Jari Aaltob80f6442004-07-27 13:29:18 +0000600 term = get_string_value ("TERM");
Jari Aaltob80f6442004-07-27 13:29:18 +0000601 emacs = get_string_value ("EMACS");
Chet Rameya0c0a002016-09-15 16:59:08 -0400602 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;
Jari Aalto31859422009-01-12 13:36:28 +0000617
618 /* Not sure any emacs terminal emulator sets TERM=emacs any more */
Chet Rameya0c0a002016-09-15 16:59:08 -0400619 no_line_editing |= STREQ (term, "emacs");
620 no_line_editing |= in_emacs && STREQ (term, "dumb");
Jari Aalto31859422009-01-12 13:36:28 +0000621
622 /* running_under_emacs == 2 for `eterm' */
Chet Rameya0c0a002016-09-15 16:59:08 -0400623 running_under_emacs = in_emacs || STREQN (term, "emacs", 5);
624 running_under_emacs += emacs_term && STREQN (term, "eterm", 5);
Jari Aalto31859422009-01-12 13:36:28 +0000625
Jari Aalto95732b42005-12-07 14:08:12 +0000626 if (running_under_emacs)
627 gnu_error_format = 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000628 }
629
630 top_level_arg_index = arg_index;
Jari Aaltob72432f1999-02-19 17:11:39 +0000631 old_errexit_flag = exit_immediately_on_error;
Jari Aalto726f6381996-08-26 18:22:31 +0000632
Jari Aalto726f6381996-08-26 18:22:31 +0000633 /* 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. */
Chet Rameya0c0a002016-09-15 16:59:08 -0400636 code = setjmp_sigs (top_level);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000637 if (code)
638 {
Chet Ramey74091dd2022-09-26 11:49:46 -0400639 if (code == EXITPROG || code == ERREXIT || code == EXITBLTIN)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000640 exit_shell (last_command_exit_value);
641 else
Jari Aaltod166f041997-06-05 14:59:13 +0000642 {
643#if defined (JOB_CONTROL)
644 /* Reset job control, since run_startup_files turned it off. */
645 set_job_control (interactive_shell);
646#endif
Jari Aaltob72432f1999-02-19 17:11:39 +0000647 /* Reset value of `set -e', since it's turned off before running
648 the startup files. */
649 exit_immediately_on_error += old_errexit_flag;
Jari Aaltod166f041997-06-05 14:59:13 +0000650 locally_skip_execution++;
651 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000652 }
Jari Aalto726f6381996-08-26 18:22:31 +0000653
654 arg_index = top_level_arg_index;
655
656 /* Execute the start-up scripts. */
657
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000658 if (interactive_shell == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000659 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000660 unbind_variable ("PS1");
661 unbind_variable ("PS2");
Jari Aalto28ef6c32001-04-06 19:14:31 +0000662 interactive = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000663#if 0
664 /* This has already been done by init_noninteractive */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000665 expand_aliases = posixly_correct;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000666#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000667 }
668 else
669 {
670 change_flag ('i', FLAG_ON);
671 interactive = 1;
672 }
673
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000674#if defined (RESTRICTED_SHELL)
Jari Aaltob72432f1999-02-19 17:11:39 +0000675 /* 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
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000680 /* If the `-r' option is supplied at invocation, make sure that the shell
681 is not in restricted mode when running the startup files. */
Jari Aaltob72432f1999-02-19 17:11:39 +0000682 saverst = restricted;
683 restricted = 0;
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000684#endif
685
Chet Rameyd233b482019-01-07 09:27:52 -0500686 /* 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
Jari Aaltob72432f1999-02-19 17:11:39 +0000702 /* The startup files are run with `set -e' temporarily disabled. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000703 if (locally_skip_execution == 0 && running_setuid == 0)
Jari Aaltob72432f1999-02-19 17:11:39 +0000704 {
Chet Ramey74091dd2022-09-26 11:49:46 -0400705 char *t;
706
Jari Aaltob72432f1999-02-19 17:11:39 +0000707 old_errexit_flag = exit_immediately_on_error;
708 exit_immediately_on_error = 0;
709
Chet Ramey74091dd2022-09-26 11:49:46 -0400710 /* 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 }
Jari Aaltob72432f1999-02-19 17:11:39 +0000717 run_startup_files ();
Chet Ramey74091dd2022-09-26 11:49:46 -0400718 if (shell_script_filename)
719 {
720 free (dollar_vars[0]);
721 dollar_vars[0] = t;
722 }
Jari Aaltob72432f1999-02-19 17:11:39 +0000723 exit_immediately_on_error += old_errexit_flag;
724 }
Jari Aalto726f6381996-08-26 18:22:31 +0000725
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000726 /* If we are invoked as `sh', turn on Posix mode. */
727 if (act_like_sh)
Jari Aaltod166f041997-06-05 14:59:13 +0000728 {
Jari Aalto95732b42005-12-07 14:08:12 +0000729 bind_variable ("POSIXLY_CORRECT", "y", 0);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000730 sv_strict_posix ("POSIXLY_CORRECT");
Jari Aaltod166f041997-06-05 14:59:13 +0000731 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000732
Jari Aalto726f6381996-08-26 18:22:31 +0000733#if defined (RESTRICTED_SHELL)
Jari Aaltocce855b1998-04-17 19:52:44 +0000734 /* Turn on the restrictions after executing the startup files. This
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000735 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;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000738 if (shell_reinitialized == 0)
739 maybe_make_restricted (shell_name);
Jari Aalto726f6381996-08-26 18:22:31 +0000740#endif /* RESTRICTED_SHELL */
741
Chet Ramey00018032011-11-21 20:51:19 -0500742#if defined (WORDEXP_OPTION)
Jari Aaltocce855b1998-04-17 19:52:44 +0000743 if (wordexp_only)
744 {
745 startup_state = 3;
Chet Rameyd233b482019-01-07 09:27:52 -0500746 last_command_exit_value = run_wordexp (argv[top_level_arg_index]);
Jari Aaltocce855b1998-04-17 19:52:44 +0000747 exit_shell (last_command_exit_value);
748 }
Chet Ramey00018032011-11-21 20:51:19 -0500749#endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000750
Chet Rameya0c0a002016-09-15 16:59:08 -0400751 cmd_init (); /* initialize the command object caches */
752 uwp_init ();
753
Jari Aaltob80f6442004-07-27 13:29:18 +0000754 if (command_execution_string)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000755 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000756 startup_state = 2;
Jari Aaltob80f6442004-07-27 13:29:18 +0000757
758 if (debugging_mode)
759 start_debugger ();
760
Jari Aalto726f6381996-08-26 18:22:31 +0000761#if defined (ONESHOT)
Jari Aaltof73dda02001-11-13 17:56:06 +0000762 executing = 1;
Jari Aaltob80f6442004-07-27 13:29:18 +0000763 run_one_command (command_execution_string);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000764 exit_shell (last_command_exit_value);
Jari Aalto726f6381996-08-26 18:22:31 +0000765#else /* ONESHOT */
Jari Aaltob80f6442004-07-27 13:29:18 +0000766 with_input_from_string (command_execution_string, "-c");
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000767 goto read_and_execute;
Jari Aalto726f6381996-08-26 18:22:31 +0000768#endif /* !ONESHOT */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000769 }
770
771 /* Get possible input filename and set up default_buffered_input or
772 default_input as appropriate. */
Chet Rameyd233b482019-01-07 09:27:52 -0500773 if (shell_script_filename)
774 open_shell_script (shell_script_filename);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000775 else if (interactive == 0)
Chet Rameya0c0a002016-09-15 16:59:08 -0400776 {
777 /* In this mode, bash is reading a script from stdin, which is a
778 pipe or redirected file. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000779#if defined (BUFFERED_INPUT)
Chet Rameya0c0a002016-09-15 16:59:08 -0400780 default_buffered_input = fileno (stdin); /* == 0 */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000781#else
Chet Rameya0c0a002016-09-15 16:59:08 -0400782 setbuf (default_input, (char *)NULL);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000783#endif /* !BUFFERED_INPUT */
Chet Rameya0c0a002016-09-15 16:59:08 -0400784 read_from_stdin = 1;
785 }
Chet Rameyd233b482019-01-07 09:27:52 -0500786 else if (top_level_arg_index == argc) /* arg index before startup files */
Chet Rameya0c0a002016-09-15 16:59:08 -0400787 /* "If there are no operands and the -c option is not specified, the -s
788 option shall be assumed." */
789 read_from_stdin = 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000790
791 set_bash_input ();
792
Chet Rameya0c0a002016-09-15 16:59:08 -0400793 if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0 && (reading_shell_script || interactive_shell == 0))
Jari Aaltob80f6442004-07-27 13:29:18 +0000794 start_debugger ();
795
Jari Aalto726f6381996-08-26 18:22:31 +0000796 /* 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. */
Jari Aalto726f6381996-08-26 18:22:31 +0000800 reset_mail_timer ();
Jari Aalto31859422009-01-12 13:36:28 +0000801 init_mail_dates ();
Jari Aalto726f6381996-08-26 18:22:31 +0000802
803#if defined (HISTORY)
804 /* Initialize the interactive history stuff. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000805 bash_initialize_history ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000806 /* 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)
Jari Aalto726f6381996-08-26 18:22:31 +0000810 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
Jari Aalto726f6381996-08-26 18:22:31 +0000818#if !defined (ONESHOT)
819 read_and_execute:
820#endif /* !ONESHOT */
821
822 shell_initialized = 1;
823
Chet Rameyd233b482019-01-07 09:27:52 -0500824 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
Jari Aalto726f6381996-08-26 18:22:31 +0000832 /* Read commands until exit condition. */
833 reader_loop ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000834 exit_shell (last_command_exit_value);
835}
Jari Aalto726f6381996-08-26 18:22:31 +0000836
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000837static 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])
853 {
854 longarg = 1;
855 arg_string++;
856 }
857
858 for (i = 0; long_args[i].name; i++)
859 {
860 if (STREQ (arg_string + 1, long_args[i].name))
861 {
862 if (long_args[i].type == Int)
863 *long_args[i].int_value = 1;
864 else if (argv[++arg_index] == 0)
865 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000866 report_error (_("%s: option requires an argument"), long_args[i].name);
867 exit (EX_BADUSAGE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000868 }
869 else
870 *long_args[i].char_value = argv[arg_index];
871
872 break;
873 }
874 }
875 if (long_args[i].name == 0)
876 {
877 if (longarg)
878 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000879 report_error (_("%s: invalid option"), argv[arg_index]);
Jari Aaltod166f041997-06-05 14:59:13 +0000880 show_shell_usage (stderr, 0);
Jari Aaltob80f6442004-07-27 13:29:18 +0000881 exit (EX_BADUSAGE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000882 }
883 break; /* No such argument. Maybe flag arg. */
884 }
885
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);
915
916 i = 1;
917 on_or_off = arg_string[0];
918 while (arg_character = arg_string[i++])
919 {
920 switch (arg_character)
921 {
922 case 'c':
923 want_pending_command = 1;
924 break;
925
Jari Aalto7117c2d2002-07-17 14:10:11 +0000926 case 'l':
927 make_login_shell = 1;
928 break;
929
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000930 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 {
Chet Ramey8868eda2020-12-06 15:51:17 -0500938 set_option_defaults ();
Jari Aaltocce855b1998-04-17 19:52:44 +0000939 list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1);
Chet Ramey8868eda2020-12-06 15:51:17 -0500940 reset_option_defaults ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000941 break;
942 }
943 if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
Jari Aaltob80f6442004-07-27 13:29:18 +0000944 exit (EX_BADUSAGE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000945 next_arg++;
946 break;
947
Jari Aaltof73dda02001-11-13 17:56:06 +0000948 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000963 case 'D':
Chet Ramey74091dd2022-09-26 11:49:46 -0400964#if defined (TRANSLATABLE_STRINGS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000965 dump_translatable_strings = 1;
Chet Ramey74091dd2022-09-26 11:49:46 -0400966#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000967 break;
968
969 default:
970 if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
971 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000972 report_error (_("%c%c: invalid option"), on_or_off, arg_character);
Jari Aaltod166f041997-06-05 14:59:13 +0000973 show_shell_usage (stderr, 0);
Jari Aaltob80f6442004-07-27 13:29:18 +0000974 exit (EX_BADUSAGE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000975 }
976 }
977 }
978 /* Can't do just a simple increment anymore -- what about
979 "bash -abouo emacs ignoreeof -hP"? */
980 arg_index = next_arg;
981 }
982
983 return (arg_index);
984}
985
986/* Exit the shell with status S. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000987void
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000988exit_shell (s)
989 int s;
990{
Chet Ramey00018032011-11-21 20:51:19 -0500991 fflush (stdout); /* XXX */
992 fflush (stderr);
993
Chet Ramey84c617e2015-01-15 10:21:08 -0500994 /* 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001002 /* Do trap[0] if defined. Allow it to override the exit status
1003 passed to us. */
Jari Aalto726f6381996-08-26 18:22:31 +00001004 if (signal_is_trapped (0))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001005 s = run_exit_trap ();
Jari Aalto726f6381996-08-26 18:22:31 +00001006
1007#if defined (PROCESS_SUBSTITUTION)
Chet Ramey8868eda2020-12-06 15:51:17 -05001008 unlink_all_fifos ();
Jari Aalto726f6381996-08-26 18:22:31 +00001009#endif /* PROCESS_SUBSTITUTION */
1010
1011#if defined (HISTORY)
Chet Rameyac50fba2014-02-26 09:36:43 -05001012 if (remember_on_history)
Jari Aalto726f6381996-08-26 18:22:31 +00001013 maybe_save_shell_history ();
1014#endif /* HISTORY */
1015
Jari Aalto31859422009-01-12 13:36:28 +00001016#if defined (COPROCESS_SUPPORT)
1017 coproc_flush ();
1018#endif
1019
Jari Aalto726f6381996-08-26 18:22:31 +00001020#if defined (JOB_CONTROL)
Jari Aaltocce855b1998-04-17 19:52:44 +00001021 /* 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
Chet Rameya0c0a002016-09-15 16:59:08 -04001026 /* 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. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001032 if (subshell_environment == 0)
1033 end_job_control ();
Jari Aalto726f6381996-08-26 18:22:31 +00001034#endif /* JOB_CONTROL */
1035
1036 /* Always return the exit status of the last command to our parent. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001037 sh_exit (s);
Jari Aalto726f6381996-08-26 18:22:31 +00001038}
1039
Jari Aaltobb706242000-03-17 21:46:59 +00001040/* A wrapper for exit that (optionally) can do other things, like malloc
1041 statistics tracing. */
1042void
1043sh_exit (s)
1044 int s;
1045{
Jari Aalto7117c2d2002-07-17 14:10:11 +00001046#if defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC)
Chet Rameyd233b482019-01-07 09:27:52 -05001047 if (malloc_trace_at_exit && (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)) == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001048 trace_malloc_stats (get_name_for_error (), (char *)NULL);
Chet Rameya0c0a002016-09-15 16:59:08 -04001049 /* mlocation_write_table (); */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001050#endif
1051
Jari Aaltobb706242000-03-17 21:46:59 +00001052 exit (s);
1053}
1054
Chet Rameyac50fba2014-02-26 09:36:43 -05001055/* 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. */
Chet Ramey74091dd2022-09-26 11:49:46 -04001067 last_command_exit_value = s;
Chet Rameyac50fba2014-02-26 09:36:43 -05001068 if (signal_is_trapped (0))
1069 s = run_exit_trap ();
1070
1071 sh_exit (s);
1072}
1073
Chet Ramey8868eda2020-12-06 15:51:17 -05001074void
1075set_exit_status (s)
1076 int s;
1077{
1078 set_pipestatus_from_exit (last_command_exit_value = s);
1079}
1080
Jari Aalto726f6381996-08-26 18:22:31 +00001081/* 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001084 for interactive shells only. (section 4.56.5.3) */
Jari Aalto726f6381996-08-26 18:22:31 +00001085
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001086/* Execute ~/.bashrc for most shells. Never execute it if
1087 ACT_LIKE_SH is set, or if NO_RC is set.
Jari Aalto726f6381996-08-26 18:22:31 +00001088
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001089 If the executable file "/usr/gnu/src/bash/foo" contains:
Jari Aalto726f6381996-08-26 18:22:31 +00001090
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001091 #!/usr/gnu/bin/bash
1092 echo hello
Jari Aalto726f6381996-08-26 18:22:31 +00001093
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001094 then:
Jari Aalto726f6381996-08-26 18:22:31 +00001095
Jari Aalto28ef6c32001-04-06 19:14:31 +00001096 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001106*/
Jari Aalto726f6381996-08-26 18:22:31 +00001107
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001108static void
1109execute_env_file (env_file)
1110 char *env_file;
1111{
1112 char *fn;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001113
1114 if (env_file && *env_file)
Jari Aalto726f6381996-08-26 18:22:31 +00001115 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001116 fn = expand_string_unsplit_to_string (env_file, Q_DOUBLE_QUOTES);
1117 if (fn && *fn)
1118 maybe_execute_file (fn, 1);
1119 FREE (fn);
Jari Aalto726f6381996-08-26 18:22:31 +00001120 }
1121}
1122
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001123static void
1124run_startup_files ()
1125{
Jari Aaltod166f041997-06-05 14:59:13 +00001126#if defined (JOB_CONTROL)
1127 int old_job_control;
1128#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00001129 int sourced_login, run_by_ssh;
Jari Aaltod166f041997-06-05 14:59:13 +00001130
Chet Ramey74091dd2022-09-26 11:49:46 -04001131#if 1 /* TAG:bash-5.3 andrew.gregory.8@gmail.com 2/21/2022 */
Jari Aaltocce855b1998-04-17 19:52:44 +00001132 /* get the rshd/sshd case out of the way first. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001133 if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
Jari Aaltob80f6442004-07-27 13:29:18 +00001134 act_like_sh == 0 && command_execution_string)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001135 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001136#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;
1141#endif
Chet Ramey74091dd2022-09-26 11:49:46 -04001142#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00001143
1144 /* If we were run by sshd or we think we were run by rshd, execute
Jari Aaltobb706242000-03-17 21:46:59 +00001145 ~/.bashrc if we are a top-level shell. */
Chet Ramey74091dd2022-09-26 11:49:46 -04001146#if 1 /* TAG:bash-5.3 */
Jari Aaltobb706242000-03-17 21:46:59 +00001147 if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
Chet Ramey74091dd2022-09-26 11:49:46 -04001148#else
1149 if (isnetconn (fileno (stdin) && shell_level < 2)
1150#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00001151 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001152#ifdef SYS_BASHRC
Jari Aaltob72432f1999-02-19 17:11:39 +00001153# if defined (__OPENNT)
1154 maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
1155# else
Jari Aaltocce855b1998-04-17 19:52:44 +00001156 maybe_execute_file (SYS_BASHRC, 1);
Jari Aaltob72432f1999-02-19 17:11:39 +00001157# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001158#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00001159 maybe_execute_file (bashrc_file, 1);
1160 return;
1161 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001162 }
1163
Jari Aaltocce855b1998-04-17 19:52:44 +00001164#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
Jari Aalto7117c2d2002-07-17 14:10:11 +00001171 /* 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
Jari Aaltobb706242000-03-17 21:46:59 +00001173 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
Jari Aaltocce855b1998-04-17 19:52:44 +00001180 {
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 }
Jari Aaltocce855b1998-04-17 19:52:44 +00001199
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001200 /* 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 }
1211
1212 /* Interactive shell or `-su' shell. */
1213 if (posixly_correct == 0) /* bash, sh */
1214 {
Jari Aaltocce855b1998-04-17 19:52:44 +00001215 if (login_shell && sourced_login++ == 0)
1216 {
1217 /* We don't execute .bashrc for login shells. */
1218 no_rc++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001219
Jari Aaltocce855b1998-04-17 19:52:44 +00001220 /* 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);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001225
Jari Aaltocce855b1998-04-17 19:52:44 +00001226 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 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001233
1234 /* bash */
1235 if (act_like_sh == 0 && no_rc == 0)
1236 {
1237#ifdef SYS_BASHRC
Jari Aaltob72432f1999-02-19 17:11:39 +00001238# if defined (__OPENNT)
1239 maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
1240# else
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001241 maybe_execute_file (SYS_BASHRC, 1);
Jari Aaltobb706242000-03-17 21:46:59 +00001242# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001243#endif
Jari Aalto28ef6c32001-04-06 19:14:31 +00001244 maybe_execute_file (bashrc_file, 1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001245 }
1246 /* sh */
1247 else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001248 execute_env_file (get_string_value ("ENV"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001249 }
1250 else /* bash --posix, sh --posix */
1251 {
1252 /* bash and sh */
1253 if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001254 execute_env_file (get_string_value ("ENV"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001255 }
Jari Aaltod166f041997-06-05 14:59:13 +00001256
1257#if defined (JOB_CONTROL)
1258 set_job_control (old_job_control);
1259#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001260}
1261
Jari Aalto726f6381996-08-26 18:22:31 +00001262#if defined (RESTRICTED_SHELL)
Jari Aaltob72432f1999-02-19 17:11:39 +00001263/* 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);
Jari Aalto95732b42005-12-07 14:08:12 +00001275 if (*temp == '-')
1276 temp++;
Jari Aaltob72432f1999-02-19 17:11:39 +00001277 return (STREQ (temp, RESTRICTED_SHELL_NAME));
1278}
1279
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001280/* 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.
Jari Aaltob72432f1999-02-19 17:11:39 +00001283 In a restricted shell, PATH, SHELL, ENV, and BASH_ENV are read-only
1284 and non-unsettable.
Jari Aalto726f6381996-08-26 18:22:31 +00001285 Do this also if `restricted' is already set to 1; maybe the shell was
1286 started with -r. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001287int
Jari Aalto726f6381996-08-26 18:22:31 +00001288maybe_make_restricted (name)
1289 char *name;
1290{
1291 char *temp;
1292
Jari Aalto7117c2d2002-07-17 14:10:11 +00001293 temp = base_pathname (name);
Jari Aaltob80f6442004-07-27 13:29:18 +00001294 if (*temp == '-')
1295 temp++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001296 if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
Jari Aalto726f6381996-08-26 18:22:31 +00001297 {
Chet Rameyd233b482019-01-07 09:27:52 -05001298#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
Jari Aalto726f6381996-08-26 18:22:31 +00001302 set_var_read_only ("PATH");
Jari Aalto726f6381996-08-26 18:22:31 +00001303 set_var_read_only ("SHELL");
Jari Aaltob72432f1999-02-19 17:11:39 +00001304 set_var_read_only ("ENV");
1305 set_var_read_only ("BASH_ENV");
Chet Ramey8868eda2020-12-06 15:51:17 -05001306 set_var_read_only ("HISTFILE");
Jari Aalto28ef6c32001-04-06 19:14:31 +00001307 restricted = 1;
Jari Aalto726f6381996-08-26 18:22:31 +00001308 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001309 return (restricted);
Jari Aalto726f6381996-08-26 18:22:31 +00001310}
1311#endif /* RESTRICTED_SHELL */
1312
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001313/* Fetch the current set of uids and gids and return 1 if we're running
1314 setuid or setgid. */
1315static int
1316uidget ()
Jari Aalto726f6381996-08-26 18:22:31 +00001317{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001318 uid_t u;
Jari Aalto726f6381996-08-26 18:22:31 +00001319
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001320 u = getuid ();
1321 if (current_user.uid != u)
Jari Aalto726f6381996-08-26 18:22:31 +00001322 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001323 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;
Jari Aalto726f6381996-08-26 18:22:31 +00001327 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001328 current_user.uid = u;
1329 current_user.gid = getgid ();
1330 current_user.euid = geteuid ();
1331 current_user.egid = getegid ();
Jari Aalto726f6381996-08-26 18:22:31 +00001332
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001333 /* 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}
Jari Aalto726f6381996-08-26 18:22:31 +00001337
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001338void
1339disable_priv_mode ()
1340{
Chet Rameya0c0a002016-09-15 16:59:08 -04001341 int e;
1342
Chet Ramey8868eda2020-12-06 15:51:17 -05001343#if HAVE_SETRESUID
1344 if (setresuid (current_user.uid, current_user.uid, current_user.uid) < 0)
1345#else
Chet Rameya0c0a002016-09-15 16:59:08 -04001346 if (setuid (current_user.uid) < 0)
Chet Ramey8868eda2020-12-06 15:51:17 -05001347#endif
Chet Rameya0c0a002016-09-15 16:59:08 -04001348 {
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 }
Chet Ramey8868eda2020-12-06 15:51:17 -05001356#if HAVE_SETRESGID
1357 if (setresgid (current_user.gid, current_user.gid, current_user.gid) < 0)
1358#else
Chet Rameya0c0a002016-09-15 16:59:08 -04001359 if (setgid (current_user.gid) < 0)
Chet Ramey8868eda2020-12-06 15:51:17 -05001360#endif
Chet Rameya0c0a002016-09-15 16:59:08 -04001361 sys_error (_("cannot set gid to %d: effective gid %d"), current_user.gid, current_user.egid);
1362
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001363 current_user.euid = current_user.uid;
1364 current_user.egid = current_user.gid;
Jari Aalto726f6381996-08-26 18:22:31 +00001365}
1366
Chet Ramey00018032011-11-21 20:51:19 -05001367#if defined (WORDEXP_OPTION)
Jari Aaltocce855b1998-04-17 19:52:44 +00001368static int
1369run_wordexp (words)
1370 char *words;
1371{
1372 int code, nw, nb;
Jari Aaltob80f6442004-07-27 13:29:18 +00001373 WORD_LIST *wl, *tl, *result;
Jari Aaltocce855b1998-04-17 19:52:44 +00001374
Chet Rameyac50fba2014-02-26 09:36:43 -05001375 code = setjmp_nosigs (top_level);
Jari Aaltocce855b1998-04-17 19:52:44 +00001376
1377 if (code != NOT_JUMPED)
1378 {
1379 switch (code)
1380 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001381 /* Some kind of throw to top_level has occurred. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001382 case FORCE_EOF:
1383 return last_command_exit_value = 127;
Jari Aaltob80f6442004-07-27 13:29:18 +00001384 case ERREXIT:
Jari Aaltocce855b1998-04-17 19:52:44 +00001385 case EXITPROG:
Chet Ramey74091dd2022-09-26 11:49:46 -04001386 case EXITBLTIN:
Jari Aaltocce855b1998-04-17 19:52:44 +00001387 return last_command_exit_value;
1388 case DISCARD:
1389 return last_command_exit_value = 1;
1390 default:
Jari Aaltob72432f1999-02-19 17:11:39 +00001391 command_error ("run_wordexp", CMDERR_BADJUMP, code, 0);
Jari Aaltocce855b1998-04-17 19:52:44 +00001392 }
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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001400 return (126);
Jari Aaltocce855b1998-04-17 19:52:44 +00001401 if (global_command == 0)
1402 {
1403 printf ("0\n0\n");
1404 return (0);
1405 }
1406 if (global_command->type != cm_simple)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001407 return (126);
Jari Aaltocce855b1998-04-17 19:52:44 +00001408 wl = global_command->value.Simple->words;
Jari Aaltob80f6442004-07-27 13:29:18 +00001409 if (protected_mode)
1410 for (tl = wl; tl; tl = tl->next)
Jari Aalto06285672006-10-10 14:15:34 +00001411 tl->word->flags |= W_NOCOMSUB|W_NOPROCSUB;
Jari Aaltocce855b1998-04-17 19:52:44 +00001412 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}
Chet Ramey00018032011-11-21 20:51:19 -05001440#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00001441
Jari Aalto726f6381996-08-26 18:22:31 +00001442#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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001445static int
Jari Aalto726f6381996-08-26 18:22:31 +00001446run_one_command (command)
1447 char *command;
1448{
1449 int code;
1450
Chet Rameyac50fba2014-02-26 09:36:43 -05001451 code = setjmp_nosigs (top_level);
Jari Aalto726f6381996-08-26 18:22:31 +00001452
1453 if (code != NOT_JUMPED)
1454 {
1455#if defined (PROCESS_SUBSTITUTION)
1456 unlink_fifo_list ();
1457#endif /* PROCESS_SUBSTITUTION */
1458 switch (code)
1459 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001460 /* Some kind of throw to top_level has occurred. */
Jari Aalto726f6381996-08-26 18:22:31 +00001461 case FORCE_EOF:
1462 return last_command_exit_value = 127;
Jari Aaltob80f6442004-07-27 13:29:18 +00001463 case ERREXIT:
Jari Aalto726f6381996-08-26 18:22:31 +00001464 case EXITPROG:
Chet Ramey74091dd2022-09-26 11:49:46 -04001465 case EXITBLTIN:
Jari Aalto726f6381996-08-26 18:22:31 +00001466 return last_command_exit_value;
1467 case DISCARD:
1468 return last_command_exit_value = 1;
1469 default:
Jari Aaltob72432f1999-02-19 17:11:39 +00001470 command_error ("run_one_command", CMDERR_BADJUMP, code, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00001471 }
1472 }
Chet Ramey8868eda2020-12-06 15:51:17 -05001473 return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST|SEVAL_RESETLINE));
Jari Aalto726f6381996-08-26 18:22:31 +00001474}
1475#endif /* ONESHOT */
1476
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001477static int
1478bind_args (argv, arg_start, arg_end, start_index)
1479 char **argv;
1480 int arg_start, arg_end, start_index;
Jari Aalto726f6381996-08-26 18:22:31 +00001481{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001482 register int i;
Chet Rameyd233b482019-01-07 09:27:52 -05001483 WORD_LIST *args, *tl;
Jari Aalto726f6381996-08-26 18:22:31 +00001484
Chet Rameyd233b482019-01-07 09:27:52 -05001485 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 }
1495
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001496 if (args)
Jari Aalto726f6381996-08-26 18:22:31 +00001497 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001498 if (start_index == 0) /* bind to $0...$n for sh -c command */
Jari Aalto726f6381996-08-26 18:22:31 +00001499 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001500 /* 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);
Jari Aaltod166f041997-06-05 14:59:13 +00001503 FREE (dollar_vars[0]);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001504 dollar_vars[0] = savestring (args->word->word);
1505 remember_args (args->next, 1);
Chet Rameyd233b482019-01-07 09:27:52 -05001506 if (debugging_mode)
1507 {
1508 push_args (args->next); /* BASH_ARGV and BASH_ARGC */
1509 bash_argv_initialized = 1;
1510 }
Jari Aalto726f6381996-08-26 18:22:31 +00001511 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001512 else /* bind to $1...$n for shell script */
Jari Aaltob80f6442004-07-27 13:29:18 +00001513 {
1514 remember_args (args, 1);
Chet Rameyd233b482019-01-07 09:27:52 -05001515 /* 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 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001523 }
Jari Aalto726f6381996-08-26 18:22:31 +00001524
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001525 dispose_words (args);
1526 }
Jari Aalto726f6381996-08-26 18:22:31 +00001527
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001528 return (i);
1529}
1530
1531void
1532unbind_args ()
1533{
1534 remember_args ((WORD_LIST *)NULL, 1);
Jari Aaltob80f6442004-07-27 13:29:18 +00001535 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;
Chet Rameya0c0a002016-09-15 16:59:08 -04001543 int r;
Jari Aaltob80f6442004-07-27 13:29:18 +00001544
1545 old_errexit = exit_immediately_on_error;
1546 exit_immediately_on_error = 0;
1547
Chet Rameya0c0a002016-09-15 16:59:08 -04001548 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 ();
Jari Aaltob80f6442004-07-27 13:29:18 +00001558
1559 exit_immediately_on_error += old_errexit;
1560#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001561}
1562
1563static int
1564open_shell_script (script_name)
1565 char *script_name;
1566{
Jari Aalto28ef6c32001-04-06 19:14:31 +00001567 int fd, e, fd_is_tty;
Jari Aaltob80f6442004-07-27 13:29:18 +00001568 char *filename, *path_filename, *t;
Jari Aaltof73dda02001-11-13 17:56:06 +00001569 char sample[80];
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001570 int sample_len;
Jari Aaltod166f041997-06-05 14:59:13 +00001571 struct stat sb;
Jari Aaltob80f6442004-07-27 13:29:18 +00001572#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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001576
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001577 filename = savestring (script_name);
1578
1579 fd = open (filename, O_RDONLY);
1580 if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
1581 {
Jari Aaltod166f041997-06-05 14:59:13 +00001582 e = errno;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001583 /* 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)
1587 {
1588 free (filename);
1589 filename = path_filename;
1590 fd = open (filename, O_RDONLY);
1591 }
Jari Aaltod166f041997-06-05 14:59:13 +00001592 else
1593 errno = e;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001594 }
1595
1596 if (fd < 0)
1597 {
Jari Aaltod166f041997-06-05 14:59:13 +00001598 e = errno;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001599 file_error (filename);
Chet Rameyd233b482019-01-07 09:27:52 -05001600#if defined (JOB_CONTROL)
1601 end_job_control (); /* just in case we were run as bash -i script */
1602#endif
Chet Rameya0c0a002016-09-15 16:59:08 -04001603 sh_exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001604 }
1605
Jari Aaltob80f6442004-07-27 13:29:18 +00001606 free (dollar_vars[0]);
Chet Ramey495aee42011-11-22 19:11:26 -05001607 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 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001613
Chet Rameya0c0a002016-09-15 16:59:08 -04001614 if (file_isdir (filename))
1615 {
1616#if defined (EISDIR)
1617 errno = EISDIR;
1618#else
1619 errno = EINVAL;
1620#endif
1621 file_error (filename);
Chet Rameyd233b482019-01-07 09:27:52 -05001622#if defined (JOB_CONTROL)
1623 end_job_control (); /* just in case we were run as bash -i script */
1624#endif
Chet Rameya0c0a002016-09-15 16:59:08 -04001625 sh_exit (EX_NOINPUT);
1626 }
1627
Jari Aaltob80f6442004-07-27 13:29:18 +00001628#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
Jari Aalto28ef6c32001-04-06 19:14:31 +00001643#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))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001651 {
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));
Jari Aaltod166f041997-06-05 14:59:13 +00001656 if (sample_len < 0)
1657 {
1658 e = errno;
1659 if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
Chet Rameya0c0a002016-09-15 16:59:08 -04001660 {
1661#if defined (EISDIR)
1662 errno = EISDIR;
1663 file_error (filename);
1664#else
1665 internal_error (_("%s: Is a directory"), filename);
1666#endif
1667 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00001668 else
Jari Aaltod166f041997-06-05 14:59:13 +00001669 {
1670 errno = e;
1671 file_error (filename);
1672 }
Chet Rameyd233b482019-01-07 09:27:52 -05001673#if defined (JOB_CONTROL)
1674 end_job_control (); /* just in case we were run as bash -i script */
1675#endif
Jari Aaltod166f041997-06-05 14:59:13 +00001676 exit (EX_NOEXEC);
1677 }
1678 else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001679 {
Jari Aalto31859422009-01-12 13:36:28 +00001680 internal_error (_("%s: cannot execute binary file"), filename);
Chet Rameyd233b482019-01-07 09:27:52 -05001681#if defined (JOB_CONTROL)
1682 end_job_control (); /* just in case we were run as bash -i script */
1683#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001684 exit (EX_BINARY_FILE);
1685 }
1686 /* Now rewind the file back to the beginning. */
1687 lseek (fd, 0L, 0);
1688 }
1689
Jari Aaltobb706242000-03-17 21:46:59 +00001690 /* 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. */
Jari Aalto31859422009-01-12 13:36:28 +00001693 fd = move_to_high_fd (fd, 1, -1);
Jari Aaltobb706242000-03-17 21:46:59 +00001694
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001695#if defined (BUFFERED_INPUT)
1696 default_buffered_input = fd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001697 SET_CLOSE_ON_EXEC (default_buffered_input);
1698#else /* !BUFFERED_INPUT */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001699 default_input = fdopen (fd, "r");
1700
1701 if (default_input == 0)
1702 {
1703 file_error (filename);
1704 exit (EX_NOTFOUND);
1705 }
1706
1707 SET_CLOSE_ON_EXEC (fd);
1708 if (fileno (default_input) != fd)
1709 SET_CLOSE_ON_EXEC (fileno (default_input));
1710#endif /* !BUFFERED_INPUT */
1711
Jari Aalto28ef6c32001-04-06 19:14:31 +00001712 /* 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)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001715 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001716 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 }
Jari Aaltof73dda02001-11-13 17:56:06 +00001726 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. */
Jari Aalto31859422009-01-12 13:36:28 +00001730 init_interactive_script ();
Jari Aalto28ef6c32001-04-06 19:14:31 +00001731
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001732 free (filename);
Chet Rameya0c0a002016-09-15 16:59:08 -04001733
1734 reading_shell_script = 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001735 return (fd);
1736}
1737
1738/* Initialize the input routines for the parser. */
1739static void
1740set_bash_input ()
1741{
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)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001746 sh_unset_nodelay_mode (default_buffered_input);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001747 else
1748#endif /* !BUFFERED_INPUT */
Jari Aalto28ef6c32001-04-06 19:14:31 +00001749 sh_unset_nodelay_mode (fileno (stdin));
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001750
1751 /* with_input_from_stdin really means `with_input_from_readline' */
1752 if (interactive && no_line_editing == 0)
1753 with_input_from_stdin ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001754#if defined (BUFFERED_INPUT)
Jari Aalto95732b42005-12-07 14:08:12 +00001755 else if (interactive == 0)
1756 with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
1757#endif /* BUFFERED_INPUT */
1758 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001759 with_input_from_stream (default_input, dollar_vars[0]);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001760}
1761
Jari Aaltocce855b1998-04-17 19:52:44 +00001762/* 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;
Jari Aalto31859422009-01-12 13:36:28 +00001776 bash_input.type = st_none; /* XXX */
Jari Aaltocce855b1998-04-17 19:52:44 +00001777 }
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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001788#if !defined (PROGRAM)
1789# define PROGRAM "bash"
Jari Aalto726f6381996-08-26 18:22:31 +00001790#endif
1791
Jari Aalto726f6381996-08-26 18:22:31 +00001792static void
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001793set_shell_name (argv0)
1794 char *argv0;
Jari Aalto726f6381996-08-26 18:22:31 +00001795{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001796 /* 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. */
Jari Aalto95732b42005-12-07 14:08:12 +00001798 shell_name = argv0 ? base_pathname (argv0) : PROGRAM;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001799
Jari Aalto06285672006-10-10 14:15:34 +00001800 if (argv0 && *argv0 == '-')
Jari Aalto7117c2d2002-07-17 14:10:11 +00001801 {
Jari Aalto06285672006-10-10 14:15:34 +00001802 if (*shell_name == '-')
1803 shell_name++;
Chet Rameyac50fba2014-02-26 09:36:43 -05001804 login_shell = 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001805 }
1806
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001807 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++;
1811
Jari Aalto95732b42005-12-07 14:08:12 +00001812 shell_name = argv0 ? argv0 : PROGRAM;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001813 FREE (dollar_vars[0]);
1814 dollar_vars[0] = savestring (shell_name);
1815
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001816 /* 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}
1822
Chet Ramey8868eda2020-12-06 15:51:17 -05001823/* 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001844static void
1845init_interactive ()
1846{
Jari Aalto31859422009-01-12 13:36:28 +00001847 expand_aliases = interactive_shell = startup_state = 1;
1848 interactive = 1;
Chet Rameya0c0a002016-09-15 16:59:08 -04001849#if defined (HISTORY)
Chet Ramey8868eda2020-12-06 15:51:17 -05001850 if (enable_history_list == -1)
1851 enable_history_list = 1; /* set default */
1852 remember_on_history = enable_history_list;
1853# if defined (BANG_HISTORY)
Chet Rameyd233b482019-01-07 09:27:52 -05001854 histexp_flag = history_expansion; /* XXX */
Chet Ramey8868eda2020-12-06 15:51:17 -05001855# endif
Chet Rameya0c0a002016-09-15 16:59:08 -04001856#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001857}
1858
1859static void
1860init_noninteractive ()
1861{
1862#if defined (HISTORY)
Chet Ramey8868eda2020-12-06 15:51:17 -05001863 if (enable_history_list == -1) /* set default */
1864 enable_history_list = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001865 bash_history_reinit (0);
1866#endif /* HISTORY */
1867 interactive_shell = startup_state = interactive = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001868 expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001869 no_line_editing = 1;
1870#if defined (JOB_CONTROL)
Chet Rameyac50fba2014-02-26 09:36:43 -05001871 /* 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);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001874#endif /* JOB_CONTROL */
Jari Aalto726f6381996-08-26 18:22:31 +00001875}
1876
Jari Aalto31859422009-01-12 13:36:28 +00001877static void
1878init_interactive_script ()
1879{
Chet Ramey8868eda2020-12-06 15:51:17 -05001880#if defined (HISTORY)
1881 if (enable_history_list == -1)
1882 enable_history_list = 1;
1883#endif
Jari Aalto31859422009-01-12 13:36:28 +00001884 init_noninteractive ();
1885 expand_aliases = interactive_shell = startup_state = 1;
Chet Rameya0c0a002016-09-15 16:59:08 -04001886#if defined (HISTORY)
Chet Ramey8868eda2020-12-06 15:51:17 -05001887 remember_on_history = enable_history_list; /* XXX */
Chet Rameya0c0a002016-09-15 16:59:08 -04001888#endif
Jari Aalto31859422009-01-12 13:36:28 +00001889}
1890
Jari Aaltod166f041997-06-05 14:59:13 +00001891void
1892get_current_user_info ()
Jari Aalto726f6381996-08-26 18:22:31 +00001893{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001894 struct passwd *entry;
Jari Aalto726f6381996-08-26 18:22:31 +00001895
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001896 /* Don't fetch this more than once. */
1897 if (current_user.user_name == 0)
1898 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001899#if defined (__TANDEM)
1900 entry = getpwnam (getlogin ());
1901#else
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001902 entry = getpwuid (current_user.uid);
Chet Rameyac50fba2014-02-26 09:36:43 -05001903#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001904 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 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001914 current_user.user_name = _("I have no name!");
1915 current_user.user_name = savestring (current_user.user_name);
Jari Aalto726f6381996-08-26 18:22:31 +00001916 current_user.shell = savestring ("/bin/sh");
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001917 current_user.home_dir = savestring ("/");
1918 }
Chet Rameya0c0a002016-09-15 16:59:08 -04001919#if defined (HAVE_GETPWENT)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001920 endpwent ();
Chet Rameya0c0a002016-09-15 16:59:08 -04001921#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001922 }
Jari Aaltod166f041997-06-05 14:59:13 +00001923}
1924
1925/* Do whatever is necessary to initialize the shell.
1926 Put new initializations in here. */
1927static void
1928shell_initialize ()
1929{
1930 char hostname[256];
Chet Rameya0c0a002016-09-15 16:59:08 -04001931 int should_be_restricted;
Jari Aaltod166f041997-06-05 14:59:13 +00001932
1933 /* Line buffer output for stderr and stdout. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001934 if (shell_initialized == 0)
Jari Aaltocce855b1998-04-17 19:52:44 +00001935 {
Jari Aaltobb706242000-03-17 21:46:59 +00001936 sh_setlinebuf (stderr);
1937 sh_setlinebuf (stdout);
Jari Aaltocce855b1998-04-17 19:52:44 +00001938 }
Jari Aaltod166f041997-06-05 14:59:13 +00001939
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 ();
Jari Aalto7117c2d2002-07-17 14:10:11 +00001949 initialize_signals (0);
Jari Aaltod166f041997-06-05 14:59:13 +00001950
1951 /* It's highly unlikely that this will change. */
1952 if (current_host_name == 0)
1953 {
1954 /* Initialize current_host_name. */
1955 if (gethostname (hostname, 255) < 0)
1956 current_host_name = "??host??";
1957 else
1958 current_host_name = savestring (hostname);
1959 }
1960
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 ();
Jari Aalto726f6381996-08-26 18:22:31 +00001966
1967 /* Initialize our interface to the tilde expander. */
1968 tilde_initialize ();
1969
Chet Rameya0c0a002016-09-15 16:59:08 -04001970#if defined (RESTRICTED_SHELL)
1971 should_be_restricted = shell_is_restricted (shell_name);
1972#endif
1973
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001974 /* 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)
Chet Rameya0c0a002016-09-15 16:59:08 -04001978 initialize_shell_variables (shell_environment, privileged_mode||restricted||should_be_restricted||running_setuid);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001979#else
1980 initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
1981#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001982
Jari Aalto726f6381996-08-26 18:22:31 +00001983 /* Initialize the data structures for storing and running jobs. */
Chet Rameyac50fba2014-02-26 09:36:43 -05001984 initialize_job_control (jobs_m_flag);
Jari Aalto726f6381996-08-26 18:22:31 +00001985
1986 /* Initialize input streams to null. */
1987 initialize_bash_input ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001988
Jari Aalto7117c2d2002-07-17 14:10:11 +00001989 initialize_flags ();
1990
Jari Aaltocce855b1998-04-17 19:52:44 +00001991 /* Initialize the shell options. Don't import the shell options
Chet Ramey495aee42011-11-22 19:11:26 -05001992 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. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001995#if defined (RESTRICTED_SHELL)
Chet Rameya0c0a002016-09-15 16:59:08 -04001996 initialize_shell_options (privileged_mode||restricted||should_be_restricted||running_setuid);
1997 initialize_bashopts (privileged_mode||restricted||should_be_restricted||running_setuid);
Jari Aaltocce855b1998-04-17 19:52:44 +00001998#else
1999 initialize_shell_options (privileged_mode||running_setuid);
Chet Ramey00018032011-11-21 20:51:19 -05002000 initialize_bashopts (privileged_mode||running_setuid);
Jari Aaltocce855b1998-04-17 19:52:44 +00002001#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002002}
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;
Chet Rameya0c0a002016-09-15 16:59:08 -04002026 forced_interactive = interactive_shell = 0;
2027 subshell_environment = running_in_background = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002028 expand_aliases = 0;
Chet Rameyd233b482019-01-07 09:27:52 -05002029 bash_argv_initialized = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002030
Chet Rameyac50fba2014-02-26 09:36:43 -05002031 /* XXX - should we set jobs_m_flag to 0 here? */
2032
Jari Aalto726f6381996-08-26 18:22:31 +00002033#if defined (HISTORY)
Chet Rameya0c0a002016-09-15 16:59:08 -04002034 bash_history_reinit (enable_history_list = 0);
Jari Aalto726f6381996-08-26 18:22:31 +00002035#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). */
Chet Rameya0c0a002016-09-15 16:59:08 -04002043 bashrc_file = DEFAULT_BASHRC;
Jari Aalto726f6381996-08-26 18:22:31 +00002044
2045 /* Delete all variables and functions. They will be reinitialized when
2046 the environment is parsed. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002047 delete_all_contexts (shell_variables);
Jari Aalto726f6381996-08-26 18:22:31 +00002048 delete_all_variables (shell_functions);
2049
Jari Aalto31859422009-01-12 13:36:28 +00002050 reinit_special_variables ();
2051
2052#if defined (READLINE)
2053 bashline_reinitialize ();
2054#endif
2055
Jari Aalto28ef6c32001-04-06 19:14:31 +00002056 shell_reinitialized = 1;
Jari Aalto726f6381996-08-26 18:22:31 +00002057}
2058
2059static void
Jari Aaltod166f041997-06-05 14:59:13 +00002060show_shell_usage (fp, extra)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002061 FILE *fp;
Jari Aaltod166f041997-06-05 14:59:13 +00002062 int extra;
Jari Aalto726f6381996-08-26 18:22:31 +00002063{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002064 int i;
2065 char *set_opts, *s, *t;
Jari Aalto726f6381996-08-26 18:22:31 +00002066
Jari Aaltod166f041997-06-05 14:59:13 +00002067 if (extra)
Jari Aalto31859422009-01-12 13:36:28 +00002068 fprintf (fp, _("GNU bash, version %s-(%s)\n"), shell_version_string (), MACHTYPE);
Jari Aaltob80f6442004-07-27 13:29:18 +00002069 fprintf (fp, _("Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n"),
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002070 shell_name, shell_name);
Jari Aaltob80f6442004-07-27 13:29:18 +00002071 fputs (_("GNU long options:\n"), fp);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002072 for (i = 0; long_args[i].name; i++)
2073 fprintf (fp, "\t--%s\n", long_args[i].name);
Jari Aalto726f6381996-08-26 18:22:31 +00002074
Jari Aaltob80f6442004-07-27 13:29:18 +00002075 fputs (_("Shell options:\n"), fp);
Chet Rameyac50fba2014-02-26 09:36:43 -05002076 fputs (_("\t-ilrsD or -c command or -O shopt_option\t\t(invocation only)\n"), fp);
Jari Aalto726f6381996-08-26 18:22:31 +00002077
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002078 for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
2079 if (STREQ (shell_builtins[i].name, "set"))
Chet Rameyd233b482019-01-07 09:27:52 -05002080 {
2081 set_opts = savestring (shell_builtins[i].short_doc);
2082 break;
2083 }
2084
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002085 if (set_opts)
Jari Aalto726f6381996-08-26 18:22:31 +00002086 {
Chet Ramey00018032011-11-21 20:51:19 -05002087 s = strchr (set_opts, '[');
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002088 if (s == 0)
2089 s = set_opts;
2090 while (*++s == '-')
2091 ;
Chet Ramey00018032011-11-21 20:51:19 -05002092 t = strchr (s, ']');
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002093 if (t)
2094 *t = '\0';
Jari Aaltob80f6442004-07-27 13:29:18 +00002095 fprintf (fp, _("\t-%s or -o option\n"), s);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002096 free (set_opts);
Jari Aalto726f6381996-08-26 18:22:31 +00002097 }
2098
Jari Aaltod166f041997-06-05 14:59:13 +00002099 if (extra)
2100 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002101 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"));
Chet Rameya0c0a002016-09-15 16:59:08 -04002104 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"));
Jari Aaltod166f041997-06-05 14:59:13 +00002107 }
Jari Aalto726f6381996-08-26 18:22:31 +00002108}
2109
Jari Aaltof73dda02001-11-13 17:56:06 +00002110static 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)
Jari Aaltob80f6442004-07-27 13:29:18 +00002132 exit (EX_BADUSAGE);
Jari Aaltof73dda02001-11-13 17:56:06 +00002133 free (shopt_alist);
2134 shopt_alist = 0;
2135 shopt_ind = shopt_len = 0;
2136}