1 diff -urNp -x '*.orig' bash-5.1.org/builtins/mkbuiltins.c bash-5.1/builtins/mkbuiltins.c
2 --- bash-5.1.org/builtins/mkbuiltins.c 2020-06-05 19:14:43.000000000 +0200
3 +++ bash-5.1/builtins/mkbuiltins.c 2021-03-21 13:21:29.803594925 +0100
4 @@ -69,10 +69,15 @@ extern char *strcpy ();
5 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
7 /* Flag values that builtins can have. */
8 +/* These flags are for the C code generator,
9 + the C which is produced (./builtin.c)
10 + includes the flags definitions found
12 #define BUILTIN_FLAG_SPECIAL 0x01
13 #define BUILTIN_FLAG_ASSIGNMENT 0x02
14 #define BUILTIN_FLAG_LOCALVAR 0x04
15 #define BUILTIN_FLAG_POSIX_BUILTIN 0x08
16 +#define BUILTIN_FLAG_REQUIRES 0x10
20 @@ -173,11 +178,19 @@ char *posix_builtins[] =
24 +/* The builtin commands that cause requirements on other files. */
25 +static char *requires_builtins[] =
27 + ".", "command", "exec", "source", "inlib",
31 /* Forward declarations. */
32 static int is_special_builtin ();
33 static int is_assignment_builtin ();
34 static int is_localvar_builtin ();
35 static int is_posix_builtin ();
36 +static int is_requires_builtin ();
38 #if !defined (HAVE_RENAME)
40 @@ -831,6 +844,8 @@ builtin_handler (self, defs, arg)
41 new->flags |= BUILTIN_FLAG_LOCALVAR;
42 if (is_posix_builtin (name))
43 new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
44 + if (is_requires_builtin (name))
45 + new->flags |= BUILTIN_FLAG_REQUIRES;
47 array_add ((char *)new, defs->builtins);
49 @@ -1250,12 +1265,13 @@ write_builtins (defs, structfile, extern
51 fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
53 - fprintf (structfile, "%s%s%s%s%s, %s_doc,\n",
54 + fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n",
55 "BUILTIN_ENABLED | STATIC_BUILTIN",
56 (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
57 (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
58 (builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "",
59 (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
60 + (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "",
61 document_name (builtin));
63 /* Don't translate short document summaries that are identical
64 @@ -1645,6 +1661,13 @@ is_posix_builtin (name)
65 return (_find_in_table (name, posix_builtins));
69 +is_requires_builtin (name)
72 + return (_find_in_table (name, requires_builtins));
75 #if !defined (HAVE_RENAME)
78 diff -urNp -x '*.orig' bash-5.1.org/builtins.h bash-5.1/builtins.h
79 --- bash-5.1.org/builtins.h 2017-04-19 15:15:48.000000000 +0200
80 +++ bash-5.1/builtins.h 2021-03-21 13:21:29.803594925 +0100
82 #define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */
83 #define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */
84 #define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */
85 +#define REQUIRES_BUILTIN 0x80 /* This builtin requires other files. */
89 diff -urNp -x '*.orig' bash-5.1.org/doc/bash.1 bash-5.1/doc/bash.1
90 --- bash-5.1.org/doc/bash.1 2020-11-18 21:03:59.000000000 +0100
91 +++ bash-5.1/doc/bash.1 2021-03-21 13:21:29.804594925 +0100
92 @@ -239,6 +239,14 @@ The shell becomes restricted (see
97 +Produce the list of files that are required for the
98 +shell script to run. This implies '-n' and is subject
99 +to the same limitations as compile time error checking checking;
100 +Command substitutions, Conditional expressions and
102 +builtin are not parsed so some dependencies may be missed.
105 Equivalent to \fB\-v\fP.
107 diff -urNp -x '*.orig' bash-5.1.org/doc/bashref.texi bash-5.1/doc/bashref.texi
108 --- bash-5.1.org/doc/bashref.texi 2021-03-21 13:21:29.428594925 +0100
109 +++ bash-5.1/doc/bashref.texi 2021-03-21 13:21:29.806594925 +0100
110 @@ -6554,6 +6554,13 @@ standard. @xref{Bash POSIX Mode}, for a
112 Make the shell a restricted shell (@pxref{The Restricted Shell}).
114 +@item --rpm-requires
115 +Produce the list of files that are required for the
116 +shell script to run. This implies '-n' and is subject
117 +to the same limitations as compile time error checking checking;
118 +Command substitutions, Conditional expressions and @command{eval}
119 +are not parsed so some dependencies may be missed.
122 Equivalent to @option{-v}. Print shell input lines as they're read.
124 diff -urNp -x '*.orig' bash-5.1.org/eval.c bash-5.1/eval.c
125 --- bash-5.1.org/eval.c 2020-08-31 16:39:51.000000000 +0200
126 +++ bash-5.1/eval.c 2021-03-21 13:21:29.806594925 +0100
127 @@ -137,7 +137,8 @@ reader_loop ()
129 if (read_command () == 0)
131 - if (interactive_shell == 0 && read_but_dont_execute)
133 + if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires))
135 set_exit_status (EXECUTION_SUCCESS);
136 dispose_command (global_command);
137 diff -urNp -x '*.orig' bash-5.1.org/execute_cmd.c bash-5.1/execute_cmd.c
138 --- bash-5.1.org/execute_cmd.c 2020-10-12 16:16:13.000000000 +0200
139 +++ bash-5.1/execute_cmd.c 2021-03-21 13:21:29.807594925 +0100
140 @@ -539,6 +539,8 @@ async_redirect_stdin ()
142 #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
144 +extern int rpm_requires;
146 /* Execute the command passed in COMMAND, perhaps doing it asynchronously.
147 COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
148 ASYNCHRONOUS, if non-zero, says to do this command in the background.
149 @@ -570,7 +572,13 @@ execute_command_internal (command, async
151 if (breaking || continuing)
152 return (last_command_exit_value);
153 - if (command == 0 || read_but_dont_execute)
154 + if (command == 0 || (read_but_dont_execute && !rpm_requires))
155 + return (EXECUTION_SUCCESS);
156 + if (rpm_requires && command->type == cm_function_def)
157 + return last_command_exit_value =
158 + execute_intern_function (command->value.Function_def->name,
159 + command->value.Function_def);
160 + if (read_but_dont_execute)
161 return (EXECUTION_SUCCESS);
164 @@ -2832,7 +2840,7 @@ execute_for_command (for_command)
165 save_line_number = line_number;
166 if (check_identifier (for_command->name, 1) == 0)
168 - if (posixly_correct && interactive_shell == 0)
169 + if (posixly_correct && interactive_shell == 0 && rpm_requires == 0)
171 last_command_exit_value = EX_BADUSAGE;
172 jump_to_top_level (ERREXIT);
173 diff -urNp -x '*.orig' bash-5.1.org/execute_cmd.h bash-5.1/execute_cmd.h
174 --- bash-5.1.org/execute_cmd.h 2020-03-03 17:39:04.000000000 +0100
175 +++ bash-5.1/execute_cmd.h 2021-03-21 13:21:29.807594925 +0100
177 #define _EXECUTE_CMD_H_
180 +#include "variables.h"
181 +#include "command.h"
184 #if defined (ARRAY_VARS)
185 struct func_array_state
186 diff -urNp -x '*.orig' bash-5.1.org/make_cmd.c bash-5.1/make_cmd.c
187 --- bash-5.1.org/make_cmd.c 2020-06-05 19:09:16.000000000 +0200
188 +++ bash-5.1/make_cmd.c 2021-03-21 13:21:29.807594925 +0100
189 @@ -828,6 +828,27 @@ make_coproc_command (name, command)
190 return (make_command (cm_coproc, (SIMPLE_COM *)temp));
194 +output_requirement (deptype, filename)
195 +const char *deptype;
198 + if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/')))
202 + if the executable is called via variable substitution we can
203 + not dermine what it is at compile time.
205 + if the executable consists only of characters not in the
206 + alphabet we do not consider it a dependency just an artifact
207 + of shell parsing (ex "exec < ${infile}").
210 + if (strpbrk(filename, alphabet_set))
211 + printf ("%s(%s)\n", deptype, filename);
214 /* Reverse the word list and redirection list in the simple command
215 has just been parsed. It seems simpler to do this here the one
216 time then by any other method that I can think of. */
217 @@ -845,6 +866,28 @@ clean_simple_command (command)
218 REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
221 + if (rpm_requires && command->value.Simple->words)
227 + cmd0 = command->value.Simple->words->word->word;
228 + b = builtin_address_internal (cmd0, 0);
230 + if (command->value.Simple->words->next)
231 + cmd1 = command->value.Simple->words->next->word->word;
234 + if ( (b->flags & REQUIRES_BUILTIN) && cmd1)
235 + output_requirement ("executable", cmd1);
237 + if (!assignment(cmd0, 0))
238 + output_requirement (find_function(cmd0) ? "function" : "executable", cmd0);
243 parser_state &= ~PST_REDIRLIST;
246 diff -urNp -x '*.orig' bash-5.1.org/shell.c bash-5.1/shell.c
247 --- bash-5.1.org/shell.c 2020-08-04 17:00:24.000000000 +0200
248 +++ bash-5.1/shell.c 2021-03-21 13:21:29.807594925 +0100
249 @@ -194,6 +194,9 @@ int have_devfd = 0;
250 /* The name of the .(shell)rc file. */
251 static char *bashrc_file = DEFAULT_BASHRC;
253 +/* Non-zero if we are finding the scripts requirements. */
256 /* Non-zero means to act more like the Bourne shell on startup. */
257 static int act_like_sh;
259 @@ -260,6 +263,7 @@ static const struct {
260 { "protected", Int, &protected_mode, (char **)0x0 },
262 { "rcfile", Charp, (int *)0x0, &bashrc_file },
263 + { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
264 #if defined (RESTRICTED_SHELL)
265 { "restricted", Int, &restricted, (char **)0x0 },
267 @@ -502,6 +506,12 @@ main (argc, argv, env)
268 if (dump_translatable_strings)
269 read_but_dont_execute = 1;
273 + read_but_dont_execute = 1;
274 + initialize_shell_builtins ();
277 if (running_setuid && privileged_mode == 0)
278 disable_priv_mode ();
280 diff -urNp -x '*.orig' bash-5.1.org/shell.h bash-5.1/shell.h
281 --- bash-5.1.org/shell.h 2020-06-05 19:10:44.000000000 +0200
282 +++ bash-5.1/shell.h 2021-03-21 13:21:29.807594925 +0100
285 #include "unwind_prot.h"
286 #include "dispose_cmd.h"
287 +#include "execute_cmd.h"
288 #include "make_cmd.h"
292 #include "pathnames.h"
294 +#include "builtins.h"
295 +#include "builtins/common.h"
297 extern int EOF_Reached;
299 @@ -99,6 +102,9 @@ extern int interactive, interactive_shel
300 extern int startup_state;
301 extern int reading_shell_script;
302 extern int shell_initialized;
303 +extern int rpm_requires;
304 +static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz"
305 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
306 extern int bash_argv_initialized;
307 extern int subshell_environment;
308 extern int current_command_number;