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