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