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