aboutsummaryrefslogtreecommitdiffstats
path: root/shell.c
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>1997-06-05 14:59:13 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:50 +0000
commitd166f048818e10cf3799aa24a174fb22835f1acc (patch)
tree1ca27f9243900f8b236d0cde6a3862002aea9e19 /shell.c
parentccc6cda312fea9f0468ee65b8f368e9653e1380b (diff)
downloadandroid_external_bash-d166f048818e10cf3799aa24a174fb22835f1acc.tar.gz
android_external_bash-d166f048818e10cf3799aa24a174fb22835f1acc.tar.bz2
android_external_bash-d166f048818e10cf3799aa24a174fb22835f1acc.zip
Imported from ../bash-2.01.tar.gz.
Diffstat (limited to 'shell.c')
-rw-r--r--shell.c156
1 files changed, 114 insertions, 42 deletions
diff --git a/shell.c b/shell.c
index 84932ee..1ec100c 100644
--- a/shell.c
+++ b/shell.c
@@ -318,7 +318,7 @@ main (argc, argv, env)
if (want_initial_help)
{
- show_shell_usage (stdout);
+ show_shell_usage (stdout, 1);
exit (EXECUTION_SUCCESS);
}
@@ -342,11 +342,6 @@ main (argc, argv, env)
if (dump_translatable_strings)
read_but_dont_execute = 1;
- /* If we're in a strict Posix.2 mode, turn on interactive comments and
- other Posix.2 things. */
- if (posixly_correct)
- posix_initialize (posixly_correct);
-
if (running_setuid && privileged_mode == 0)
disable_priv_mode ();
@@ -400,6 +395,17 @@ main (argc, argv, env)
}
#endif /* CLOSE_FDS_AT_LOGIN */
+ /* If we're in a strict Posix.2 mode, turn on interactive comments and
+ other Posix.2 things. */
+ if (posixly_correct)
+ {
+ posix_initialize (posixly_correct);
+#if defined (READLINE)
+ if (interactive_shell)
+ posix_readline_initialize (posixly_correct);
+#endif
+ }
+
/* From here on in, the shell must be a normal functioning shell.
Variables from the environment are expected to be set, etc. */
shell_initialize ();
@@ -428,7 +434,13 @@ main (argc, argv, env)
if (code == EXITPROG)
exit_shell (last_command_exit_value);
else
- locally_skip_execution++;
+ {
+#if defined (JOB_CONTROL)
+ /* Reset job control, since run_startup_files turned it off. */
+ set_job_control (interactive_shell);
+#endif
+ locally_skip_execution++;
+ }
}
arg_index = top_level_arg_index;
@@ -452,7 +464,13 @@ main (argc, argv, env)
/* If we are invoked as `sh', turn on Posix mode. */
if (act_like_sh)
- posix_initialize (posixly_correct = 1);
+ {
+ posix_initialize (posixly_correct = 1);
+#if defined (READLINE)
+ if (interactive_shell)
+ posix_readline_initialize (posixly_correct);
+#endif
+ }
#if defined (RESTRICTED_SHELL)
/* Turn on the restrictions after parsing the startup files. */
@@ -568,6 +586,7 @@ parse_long_options (argv, arg_start, arg_end)
if (longarg)
{
report_error ("%s: unrecognized option", argv[arg_index]);
+ show_shell_usage (stderr, 0);
exit (EX_USAGE);
}
break; /* No such argument. Maybe flag arg. */
@@ -621,7 +640,7 @@ parse_shell_options (argv, arg_start, arg_end)
o_option = argv[next_arg];
if (o_option == 0)
{
- list_minus_o_opts ();
+ list_minus_o_opts (-1);
break;
}
if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
@@ -637,6 +656,7 @@ parse_shell_options (argv, arg_start, arg_end)
if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
{
report_error ("%c%c: unrecognized option", on_or_off, arg_character);
+ show_shell_usage (stderr, 0);
exit (EX_USAGE);
}
}
@@ -730,6 +750,10 @@ execute_env_file (env_file)
static void
run_startup_files ()
{
+#if defined (JOB_CONTROL)
+ int old_job_control;
+#endif
+
/* get the rshd case out of the way first. */
if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
act_like_sh == 0 && local_pending_command && isnetconn (fileno (stdin)))
@@ -753,6 +777,11 @@ run_startup_files ()
return;
}
+#if defined (JOB_CONTROL)
+ /* Startup files should be run without job control enabled. */
+ old_job_control = set_job_control (0);
+#endif
+
/* Interactive shell or `-su' shell. */
if (posixly_correct == 0) /* bash, sh */
{
@@ -791,6 +820,10 @@ run_startup_files ()
if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
execute_env_file (get_string_value ("ENV"));
}
+
+#if defined (JOB_CONTROL)
+ set_job_control (old_job_control);
+#endif
}
#if defined (RESTRICTED_SHELL)
@@ -880,7 +913,7 @@ run_one_command (command)
programming_error ("run_one_command: bad jump: code %d", code);
}
}
- return (parse_and_execute (savestring (command), "-c", -1));
+ return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST));
}
#endif /* ONESHOT */
@@ -902,6 +935,7 @@ bind_args (argv, arg_start, arg_end, start_index)
/* Posix.2 4.56.3 says that the first argument after sh -c command
becomes $0, and the rest of the arguments become $1...$n */
shell_name = savestring (args->word->word);
+ FREE (dollar_vars[0]);
dollar_vars[0] = savestring (args->word->word);
remember_args (args->next, 1);
}
@@ -924,10 +958,11 @@ static int
open_shell_script (script_name)
char *script_name;
{
- int fd;
+ int fd, e;
char *filename, *path_filename;
unsigned char sample[80];
int sample_len;
+ struct stat sb;
free (dollar_vars[0]);
dollar_vars[0] = savestring (script_name);
@@ -936,6 +971,7 @@ open_shell_script (script_name)
fd = open (filename, O_RDONLY);
if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
{
+ e = errno;
/* If it's not in the current directory, try looking through PATH
for it. */
path_filename = find_path_file (script_name);
@@ -945,11 +981,13 @@ open_shell_script (script_name)
filename = path_filename;
fd = open (filename, O_RDONLY);
}
+ else
+ errno = e;
}
if (fd < 0)
{
- int e = errno;
+ e = errno;
file_error (filename);
exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
}
@@ -961,7 +999,19 @@ open_shell_script (script_name)
according to the same tests done by execute_simple_command (),
and report an error and exit if it is. */
sample_len = read (fd, sample, sizeof (sample));
- if (sample_len > 0 && (check_binary_file (sample, sample_len)))
+ if (sample_len < 0)
+ {
+ e = errno;
+ if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
+ internal_error ("%s: is a directory", filename);
+ else
+ {
+ errno = e;
+ file_error (filename);
+ }
+ exit (EX_NOEXEC);
+ }
+ else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
{
internal_error ("%s: cannot execute binary file", filename);
exit (EX_BINARY_FILE);
@@ -972,17 +1022,20 @@ open_shell_script (script_name)
#if defined (BUFFERED_INPUT)
default_buffered_input = fd;
+# if 0
+ /* This is never executed. */
if (default_buffered_input == -1)
{
file_error (filename);
exit (EX_NOTFOUND);
}
+# endif
SET_CLOSE_ON_EXEC (default_buffered_input);
#else /* !BUFFERED_INPUT */
/* Open the script. But try to move the file descriptor to a randomly
large one, in the hopes that any descriptors used by the script will
not match with ours. */
- fd = move_to_high_fd (fd, 0);
+ fd = move_to_high_fd (fd, 0, -1);
default_input = fdopen (fd, "r");
@@ -998,6 +1051,7 @@ open_shell_script (script_name)
#endif /* !BUFFERED_INPUT */
if (interactive_shell == 0 || isatty (fd) == 0)
+ /* XXX - does this really need to be called again here? */
init_noninteractive ();
else
{
@@ -1102,12 +1156,38 @@ init_noninteractive ()
#endif /* JOB_CONTROL */
}
+void
+get_current_user_info ()
+{
+ struct passwd *entry;
+
+ /* Don't fetch this more than once. */
+ if (current_user.user_name == 0)
+ {
+ entry = getpwuid (current_user.uid);
+ if (entry)
+ {
+ current_user.user_name = savestring (entry->pw_name);
+ current_user.shell = (entry->pw_shell && entry->pw_shell[0])
+ ? savestring (entry->pw_shell)
+ : savestring ("/bin/sh");
+ current_user.home_dir = savestring (entry->pw_dir);
+ }
+ else
+ {
+ current_user.user_name = savestring ("I have no name!");
+ current_user.shell = savestring ("/bin/sh");
+ current_user.home_dir = savestring ("/");
+ }
+ endpwent ();
+ }
+}
+
/* Do whatever is necessary to initialize the shell.
Put new initializations in here. */
static void
shell_initialize ()
{
- struct passwd *entry;
char hostname[256];
/* Line buffer output for stderr and stdout. */
@@ -1128,33 +1208,18 @@ shell_initialize ()
/* It's highly unlikely that this will change. */
if (current_host_name == 0)
{
- /* Initialize current_user.name and current_host_name. */
+ /* Initialize current_host_name. */
if (gethostname (hostname, 255) < 0)
current_host_name = "??host??";
else
current_host_name = savestring (hostname);
}
- /* Don't fetch this more than once. */
- if (current_user.user_name == 0)
- {
- entry = getpwuid (current_user.uid);
- if (entry)
- {
- current_user.user_name = savestring (entry->pw_name);
- current_user.shell = (entry->pw_shell && entry->pw_shell[0])
- ? savestring (entry->pw_shell)
- : savestring ("/bin/sh");
- current_user.home_dir = savestring (entry->pw_dir);
- }
- else
- {
- current_user.user_name = savestring ("I have no name!");
- current_user.shell = savestring ("/bin/sh");
- current_user.home_dir = savestring ("/");
- }
- endpwent ();
- }
+ /* Initialize the stuff in current_user that comes from the password
+ file. We don't need to do this right away if the shell is not
+ interactive. */
+ if (interactive_shell)
+ get_current_user_info ();
/* Initialize our interface to the tilde expander. */
tilde_initialize ();
@@ -1168,11 +1233,13 @@ shell_initialize ()
initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
#endif
+#if 0
/* Initialize filename hash tables. */
initialize_filename_hashing ();
+#endif
/* Initialize the data structures for storing and running jobs. */
- initialize_jobs ();
+ initialize_job_control (0);
/* Initialize input streams to null. */
initialize_bash_input ();
@@ -1230,13 +1297,15 @@ shell_reinitialize ()
}
static void
-show_shell_usage (fp)
+show_shell_usage (fp, extra)
FILE *fp;
+ int extra;
{
int i;
char *set_opts, *s, *t;
- fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE);
+ if (extra)
+ fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE);
fprintf (fp, "Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n",
shell_name, shell_name);
fputs ("GNU long options:\n", fp);
@@ -1263,9 +1332,12 @@ show_shell_usage (fp)
free (set_opts);
}
- fprintf (fp, "Type `%s -c \"help set\"' for more information about shell options.\n", shell_name);
- fprintf (fp, "Type `%s -c help' for more information about shell builtin commands.\n", shell_name);
- fprintf (fp, "Use the `bashbug' command to report bugs.\n");
+ if (extra)
+ {
+ fprintf (fp, "Type `%s -c \"help set\"' for more information about shell options.\n", shell_name);
+ fprintf (fp, "Type `%s -c help' for more information about shell builtin commands.\n", shell_name);
+ fprintf (fp, "Use the `bashbug' command to report bugs.\n");
+ }
}
/* The second and subsequent conditions must match those used to decide