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