|
|
3fb13f |
diff --git a/builtins.h b/builtins.h
|
|
|
3fb13f |
index 0cfea18..a6ef958 100644
|
|
|
3fb13f |
--- a/builtins.h
|
|
|
3fb13f |
+++ b/builtins.h
|
|
|
3fb13f |
@@ -42,6 +42,7 @@
|
|
|
3fb13f |
#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */
|
|
|
3fb13f |
#define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */
|
|
|
3fb13f |
#define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */
|
|
|
3fb13f |
+#define REQUIRES_BUILTIN 0x80 /* This builtin requires other files. */
|
|
|
3fb13f |
|
|
|
3fb13f |
#define BASE_INDENT 4
|
|
|
3fb13f |
|
|
|
3fb13f |
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
|
|
|
3fb13f |
index 4f51201..283bfea 100644
|
|
|
3fb13f |
--- a/builtins/mkbuiltins.c
|
|
|
3fb13f |
+++ b/builtins/mkbuiltins.c
|
|
|
3fb13f |
@@ -69,10 +69,15 @@ extern char *strcpy ();
|
|
|
3fb13f |
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
|
|
3fb13f |
|
|
|
3fb13f |
/* Flag values that builtins can have. */
|
|
|
3fb13f |
+/* These flags are for the C code generator,
|
|
|
3fb13f |
+ the C which is produced (./builtin.c)
|
|
|
3fb13f |
+ includes the flags definitions found
|
|
|
3fb13f |
+ in ../builtins.h */
|
|
|
3fb13f |
#define BUILTIN_FLAG_SPECIAL 0x01
|
|
|
3fb13f |
#define BUILTIN_FLAG_ASSIGNMENT 0x02
|
|
|
3fb13f |
#define BUILTIN_FLAG_LOCALVAR 0x04
|
|
|
3fb13f |
#define BUILTIN_FLAG_POSIX_BUILTIN 0x08
|
|
|
3fb13f |
+#define BUILTIN_FLAG_REQUIRES 0x10
|
|
|
3fb13f |
|
|
|
3fb13f |
#define BASE_INDENT 4
|
|
|
3fb13f |
|
|
|
3fb13f |
@@ -173,11 +178,20 @@ char *posix_builtins[] =
|
|
|
3fb13f |
(char *)NULL
|
|
|
3fb13f |
};
|
|
|
3fb13f |
|
|
|
3fb13f |
+/* The builtin commands that cause requirements on other files. */
|
|
|
3fb13f |
+static char *requires_builtins[] =
|
|
|
3fb13f |
+{
|
|
|
3fb13f |
+ ".", "command", "exec", "source", "inlib",
|
|
|
3fb13f |
+ (char *)NULL
|
|
|
3fb13f |
+};
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+
|
|
|
3fb13f |
/* Forward declarations. */
|
|
|
3fb13f |
static int is_special_builtin ();
|
|
|
3fb13f |
static int is_assignment_builtin ();
|
|
|
3fb13f |
static int is_localvar_builtin ();
|
|
|
3fb13f |
static int is_posix_builtin ();
|
|
|
3fb13f |
+static int is_requires_builtin ();
|
|
|
3fb13f |
|
|
|
3fb13f |
#if !defined (HAVE_RENAME)
|
|
|
3fb13f |
static int rename ();
|
|
|
3fb13f |
@@ -831,6 +845,9 @@ builtin_handler (self, defs, arg)
|
|
|
3fb13f |
new->flags |= BUILTIN_FLAG_LOCALVAR;
|
|
|
3fb13f |
if (is_posix_builtin (name))
|
|
|
3fb13f |
new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
|
|
|
3fb13f |
+ if (is_requires_builtin (name))
|
|
|
3fb13f |
+ new->flags |= BUILTIN_FLAG_REQUIRES;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
|
|
|
3fb13f |
array_add ((char *)new, defs->builtins);
|
|
|
3fb13f |
building_builtin = 1;
|
|
|
3fb13f |
@@ -1250,12 +1267,13 @@ write_builtins (defs, structfile, externfile)
|
|
|
3fb13f |
else
|
|
|
3fb13f |
fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
|
|
|
3fb13f |
|
|
|
3fb13f |
- fprintf (structfile, "%s%s%s%s%s, %s_doc,\n",
|
|
|
3fb13f |
+ fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n",
|
|
|
3fb13f |
"BUILTIN_ENABLED | STATIC_BUILTIN",
|
|
|
3fb13f |
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
|
|
|
3fb13f |
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
|
|
|
3fb13f |
(builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "",
|
|
|
3fb13f |
(builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
|
|
|
3fb13f |
+ (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "",
|
|
|
3fb13f |
document_name (builtin));
|
|
|
3fb13f |
|
|
|
3fb13f |
/* Don't translate short document summaries that are identical
|
|
|
3fb13f |
@@ -1645,6 +1663,13 @@ is_posix_builtin (name)
|
|
|
3fb13f |
return (_find_in_table (name, posix_builtins));
|
|
|
3fb13f |
}
|
|
|
3fb13f |
|
|
|
3fb13f |
+static int
|
|
|
3fb13f |
+is_requires_builtin (name)
|
|
|
3fb13f |
+ char *name;
|
|
|
3fb13f |
+{
|
|
|
3fb13f |
+ return (_find_in_table (name, requires_builtins));
|
|
|
3fb13f |
+}
|
|
|
3fb13f |
+
|
|
|
3fb13f |
#if !defined (HAVE_RENAME)
|
|
|
3fb13f |
static int
|
|
|
3fb13f |
rename (from, to)
|
|
|
3fb13f |
diff --git a/doc/bash.1 b/doc/bash.1
|
|
|
3fb13f |
index c21e877..04ce845 100644
|
|
|
3fb13f |
--- a/doc/bash.1
|
|
|
3fb13f |
+++ b/doc/bash.1
|
|
|
3fb13f |
@@ -238,6 +238,14 @@ The shell becomes restricted (see
|
|
|
3fb13f |
.B "RESTRICTED SHELL"
|
|
|
3fb13f |
below).
|
|
|
3fb13f |
.TP
|
|
|
3fb13f |
+.B \-\-rpm-requires
|
|
|
3fb13f |
+Produce the list of files that are required for the
|
|
|
3fb13f |
+shell script to run. This implies '-n' and is subject
|
|
|
3fb13f |
+to the same limitations as compile time error checking checking;
|
|
|
3fb13f |
+Command substitutions, Conditional expressions and
|
|
|
3fb13f |
+.BR eval
|
|
|
3fb13f |
+builtin are not parsed so some dependencies may be missed.
|
|
|
3fb13f |
+.TP
|
|
|
3fb13f |
.B \-\-verbose
|
|
|
3fb13f |
Equivalent to \fB\-v\fP.
|
|
|
3fb13f |
.TP
|
|
|
3fb13f |
diff --git a/doc/bashref.texi b/doc/bashref.texi
|
|
|
3fb13f |
index 06957b6..e3fe925 100644
|
|
|
3fb13f |
--- a/doc/bashref.texi
|
|
|
3fb13f |
+++ b/doc/bashref.texi
|
|
|
3fb13f |
@@ -6243,6 +6243,13 @@ standard. @xref{Bash POSIX Mode}, for a description of the Bash
|
|
|
3fb13f |
@item --restricted
|
|
|
3fb13f |
Make the shell a restricted shell (@pxref{The Restricted Shell}).
|
|
|
3fb13f |
|
|
|
3fb13f |
+@item --rpm-requires
|
|
|
3fb13f |
+Produce the list of files that are required for the
|
|
|
3fb13f |
+shell script to run. This implies '-n' and is subject
|
|
|
3fb13f |
+to the same limitations as compile time error checking checking;
|
|
|
3fb13f |
+Command substitutions, Conditional expressions and @command{eval}
|
|
|
3fb13f |
+are not parsed so some dependencies may be missed.
|
|
|
3fb13f |
+
|
|
|
3fb13f |
@item --verbose
|
|
|
3fb13f |
Equivalent to @option{-v}. Print shell input lines as they're read.
|
|
|
3fb13f |
|
|
|
3fb13f |
diff --git a/eval.c b/eval.c
|
|
|
3fb13f |
index db863e7..5a5af32 100644
|
|
|
3fb13f |
--- a/eval.c
|
|
|
3fb13f |
+++ b/eval.c
|
|
|
3fb13f |
@@ -56,6 +56,7 @@ extern int need_here_doc;
|
|
|
3fb13f |
extern int current_command_number, current_command_line_count, line_number;
|
|
|
3fb13f |
extern int expand_aliases;
|
|
|
3fb13f |
extern char *ps0_prompt;
|
|
|
3fb13f |
+extern int rpm_requires;
|
|
|
3fb13f |
|
|
|
3fb13f |
#if defined (HAVE_POSIX_SIGNALS)
|
|
|
3fb13f |
extern sigset_t top_level_mask;
|
|
|
3fb13f |
@@ -148,7 +149,7 @@ reader_loop ()
|
|
|
3fb13f |
|
|
|
3fb13f |
if (read_command () == 0)
|
|
|
3fb13f |
{
|
|
|
3fb13f |
- if (interactive_shell == 0 && read_but_dont_execute)
|
|
|
3fb13f |
+ if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires))
|
|
|
3fb13f |
{
|
|
|
3fb13f |
last_command_exit_value = EXECUTION_SUCCESS;
|
|
|
3fb13f |
dispose_command (global_command);
|
|
|
3fb13f |
diff --git a/execute_cmd.c b/execute_cmd.c
|
|
|
3fb13f |
index b5cd405..88c7a5c 100644
|
|
|
3fb13f |
--- a/execute_cmd.c
|
|
|
3fb13f |
+++ b/execute_cmd.c
|
|
|
3fb13f |
@@ -533,6 +533,8 @@ async_redirect_stdin ()
|
|
|
3fb13f |
|
|
|
3fb13f |
#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
|
|
|
3fb13f |
|
|
|
3fb13f |
+extern int rpm_requires;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
/* Execute the command passed in COMMAND, perhaps doing it asynchronously.
|
|
|
3fb13f |
COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
|
|
|
3fb13f |
ASYNCHROUNOUS, if non-zero, says to do this command in the background.
|
|
|
3fb13f |
@@ -565,7 +567,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
|
|
3fb13f |
|
|
|
3fb13f |
if (breaking || continuing)
|
|
|
3fb13f |
return (last_command_exit_value);
|
|
|
3fb13f |
- if (command == 0 || read_but_dont_execute)
|
|
|
3fb13f |
+ if (command == 0 || (read_but_dont_execute && !rpm_requires))
|
|
|
3fb13f |
+ return (EXECUTION_SUCCESS);
|
|
|
3fb13f |
+ if (rpm_requires && command->type == cm_function_def)
|
|
|
3fb13f |
+ return last_command_exit_value =
|
|
|
3fb13f |
+ execute_intern_function (command->value.Function_def->name,
|
|
|
3fb13f |
+ command->value.Function_def);
|
|
|
3fb13f |
+ if (read_but_dont_execute)
|
|
|
3fb13f |
return (EXECUTION_SUCCESS);
|
|
|
3fb13f |
|
|
|
3fb13f |
QUIT;
|
|
|
3fb13f |
@@ -5752,7 +5760,7 @@ execute_intern_function (name, funcdef)
|
|
|
3fb13f |
|
|
|
3fb13f |
if (check_identifier (name, posixly_correct) == 0)
|
|
|
3fb13f |
{
|
|
|
3fb13f |
- if (posixly_correct && interactive_shell == 0)
|
|
|
3fb13f |
+ if (posixly_correct && interactive_shell == 0 && rpm_requires == 0)
|
|
|
3fb13f |
{
|
|
|
3fb13f |
last_command_exit_value = EX_BADUSAGE;
|
|
|
3fb13f |
jump_to_top_level (ERREXIT);
|
|
|
3fb13f |
diff --git a/execute_cmd.h b/execute_cmd.h
|
|
|
3fb13f |
index 62bec82..d42dc85 100644
|
|
|
3fb13f |
--- a/execute_cmd.h
|
|
|
3fb13f |
+++ b/execute_cmd.h
|
|
|
3fb13f |
@@ -22,6 +22,8 @@
|
|
|
3fb13f |
#define _EXECUTE_CMD_H_
|
|
|
3fb13f |
|
|
|
3fb13f |
#include "stdc.h"
|
|
|
3fb13f |
+#include "variables.h"
|
|
|
3fb13f |
+#include "command.h"
|
|
|
3fb13f |
|
|
|
3fb13f |
#if defined (ARRAY_VARS)
|
|
|
3fb13f |
struct func_array_state
|
|
|
3fb13f |
diff --git a/make_cmd.c b/make_cmd.c
|
|
|
3fb13f |
index b42e9ff..a982fe0 100644
|
|
|
3fb13f |
--- a/make_cmd.c
|
|
|
3fb13f |
+++ b/make_cmd.c
|
|
|
3fb13f |
@@ -42,11 +42,15 @@
|
|
|
3fb13f |
#include "flags.h"
|
|
|
3fb13f |
#include "make_cmd.h"
|
|
|
3fb13f |
#include "dispose_cmd.h"
|
|
|
3fb13f |
+#include "execute_cmd.h"
|
|
|
3fb13f |
#include "variables.h"
|
|
|
3fb13f |
#include "subst.h"
|
|
|
3fb13f |
#include "input.h"
|
|
|
3fb13f |
#include "ocache.h"
|
|
|
3fb13f |
#include "externs.h"
|
|
|
3fb13f |
+#include "builtins.h"
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+#include "builtins/common.h"
|
|
|
3fb13f |
|
|
|
3fb13f |
#if defined (JOB_CONTROL)
|
|
|
3fb13f |
#include "jobs.h"
|
|
|
3fb13f |
@@ -57,6 +61,10 @@
|
|
|
3fb13f |
extern int line_number, current_command_line_count, parser_state;
|
|
|
3fb13f |
extern int last_command_exit_value;
|
|
|
3fb13f |
extern int shell_initialized;
|
|
|
3fb13f |
+extern int rpm_requires;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz"
|
|
|
3fb13f |
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
3fb13f |
|
|
|
3fb13f |
int here_doc_first_line = 0;
|
|
|
3fb13f |
|
|
|
3fb13f |
@@ -839,6 +847,27 @@ make_coproc_command (name, command)
|
|
|
3fb13f |
return (make_command (cm_coproc, (SIMPLE_COM *)temp));
|
|
|
3fb13f |
}
|
|
|
3fb13f |
|
|
|
3fb13f |
+static void
|
|
|
3fb13f |
+output_requirement (deptype, filename)
|
|
|
3fb13f |
+const char *deptype;
|
|
|
3fb13f |
+char *filename;
|
|
|
3fb13f |
+{
|
|
|
3fb13f |
+ if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/')))
|
|
|
3fb13f |
+ return;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+ /*
|
|
|
3fb13f |
+ if the executable is called via variable substitution we can
|
|
|
3fb13f |
+ not dermine what it is at compile time.
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+ if the executable consists only of characters not in the
|
|
|
3fb13f |
+ alphabet we do not consider it a dependency just an artifact
|
|
|
3fb13f |
+ of shell parsing (ex "exec < ${infile}").
|
|
|
3fb13f |
+ */
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+ if (strpbrk(filename, alphabet_set))
|
|
|
3fb13f |
+ printf ("%s(%s)\n", deptype, filename);
|
|
|
3fb13f |
+}
|
|
|
3fb13f |
+
|
|
|
3fb13f |
/* Reverse the word list and redirection list in the simple command
|
|
|
3fb13f |
has just been parsed. It seems simpler to do this here the one
|
|
|
3fb13f |
time then by any other method that I can think of. */
|
|
|
3fb13f |
@@ -856,6 +885,27 @@ clean_simple_command (command)
|
|
|
3fb13f |
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
|
|
|
3fb13f |
}
|
|
|
3fb13f |
|
|
|
3fb13f |
+ if (rpm_requires && command->value.Simple->words)
|
|
|
3fb13f |
+ {
|
|
|
3fb13f |
+ char *cmd0;
|
|
|
3fb13f |
+ char *cmd1;
|
|
|
3fb13f |
+ struct builtin *b;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+ cmd0 = command->value.Simple->words->word->word;
|
|
|
3fb13f |
+ b = builtin_address_internal (cmd0, 0);
|
|
|
3fb13f |
+ cmd1 = 0;
|
|
|
3fb13f |
+ if (command->value.Simple->words->next)
|
|
|
3fb13f |
+ cmd1 = command->value.Simple->words->next->word->word;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
+ if (b) {
|
|
|
3fb13f |
+ if ( (b->flags & REQUIRES_BUILTIN) && cmd1)
|
|
|
3fb13f |
+ output_requirement ("executable", cmd1);
|
|
|
3fb13f |
+ } else {
|
|
|
3fb13f |
+ if (!assignment(cmd0, 0))
|
|
|
3fb13f |
+ output_requirement (find_function(cmd0) ? "function" : "executable", cmd0);
|
|
|
3fb13f |
+ }
|
|
|
3fb13f |
+ } /*rpm_requires*/
|
|
|
3fb13f |
+
|
|
|
3fb13f |
parser_state &= ~PST_REDIRLIST;
|
|
|
3fb13f |
return (command);
|
|
|
3fb13f |
}
|
|
|
3fb13f |
diff --git a/shell.c b/shell.c
|
|
|
3fb13f |
index 7f63969..a0fb7ce 100644
|
|
|
3fb13f |
--- a/shell.c
|
|
|
3fb13f |
+++ b/shell.c
|
|
|
3fb13f |
@@ -201,6 +201,9 @@ int have_devfd = 0;
|
|
|
3fb13f |
/* The name of the .(shell)rc file. */
|
|
|
3fb13f |
static char *bashrc_file = DEFAULT_BASHRC;
|
|
|
3fb13f |
|
|
|
3fb13f |
+/* Non-zero if we are finding the scripts requirements. */
|
|
|
3fb13f |
+int rpm_requires;
|
|
|
3fb13f |
+
|
|
|
3fb13f |
/* Non-zero means to act more like the Bourne shell on startup. */
|
|
|
3fb13f |
static int act_like_sh;
|
|
|
3fb13f |
|
|
|
3fb13f |
@@ -264,6 +267,7 @@ static const struct {
|
|
|
3fb13f |
{ "protected", Int, &protected_mode, (char **)0x0 },
|
|
|
3fb13f |
#endif
|
|
|
3fb13f |
{ "rcfile", Charp, (int *)0x0, &bashrc_file },
|
|
|
3fb13f |
+ { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
|
|
|
3fb13f |
#if defined (RESTRICTED_SHELL)
|
|
|
3fb13f |
{ "restricted", Int, &restricted, (char **)0x0 },
|
|
|
3fb13f |
#endif
|
|
|
3fb13f |
@@ -500,6 +504,12 @@ main (argc, argv, env)
|
|
|
3fb13f |
if (dump_translatable_strings)
|
|
|
3fb13f |
read_but_dont_execute = 1;
|
|
|
3fb13f |
|
|
|
3fb13f |
+ if (rpm_requires)
|
|
|
3fb13f |
+ {
|
|
|
3fb13f |
+ read_but_dont_execute = 1;
|
|
|
3fb13f |
+ initialize_shell_builtins ();
|
|
|
3fb13f |
+ }
|
|
|
3fb13f |
+
|
|
|
3fb13f |
if (running_setuid && privileged_mode == 0)
|
|
|
3fb13f |
disable_priv_mode ();
|
|
|
3fb13f |
|
|
|
3fb13f |
--
|
|
|
3fb13f |
2.9.3
|
|
|
3fb13f |
|