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