mirror of
https://github.com/sheumann/hush.git
synced 2024-12-22 14:30:31 +00:00
Merge commit '7b25b1c5b2794a499c8ae99db75830a6d564561e'
# Conflicts: # shell/hush.c
This commit is contained in:
commit
0eb3794f57
78
shell/hush.c
78
shell/hush.c
@ -741,6 +741,13 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Can be extended to handle a FIXME in setup_redirects about not saving script fds */
|
||||||
|
struct FILE_list {
|
||||||
|
struct FILE_list *next;
|
||||||
|
FILE *fp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* "Globals" within this file */
|
/* "Globals" within this file */
|
||||||
/* Sorted roughly by size (smaller offsets == smaller code) */
|
/* Sorted roughly by size (smaller offsets == smaller code) */
|
||||||
struct globals {
|
struct globals {
|
||||||
@ -839,6 +846,9 @@ struct globals {
|
|||||||
unsigned count_SIGCHLD;
|
unsigned count_SIGCHLD;
|
||||||
unsigned handled_SIGCHLD;
|
unsigned handled_SIGCHLD;
|
||||||
smallint we_have_children;
|
smallint we_have_children;
|
||||||
|
#endif
|
||||||
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
|
struct FILE_list *FILE_list;
|
||||||
#endif
|
#endif
|
||||||
/* Which signals have non-DFL handler (even with no traps set)?
|
/* Which signals have non-DFL handler (even with no traps set)?
|
||||||
* Set at the start to:
|
* Set at the start to:
|
||||||
@ -1339,6 +1349,54 @@ static void free_strings(char **strings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Manipulating the list of open FILEs */
|
||||||
|
static FILE *remember_FILE(FILE *fp)
|
||||||
|
{
|
||||||
|
if (fp) {
|
||||||
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
|
struct FILE_list *n = xmalloc(sizeof(*n));
|
||||||
|
n->fp = fp;
|
||||||
|
n->next = G.FILE_list;
|
||||||
|
G.FILE_list = n;
|
||||||
|
#endif
|
||||||
|
close_on_exec_on(fileno(fp));
|
||||||
|
}
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
|
static void close_all_FILE_list(void)
|
||||||
|
{
|
||||||
|
struct FILE_list *fl = G.FILE_list;
|
||||||
|
while (fl) {
|
||||||
|
/* fclose would also free FILE object.
|
||||||
|
* It is disastrous if we share memory with a vforked parent.
|
||||||
|
* I'm not sure we never come here after vfork.
|
||||||
|
* Therefore just close fd, nothing more.
|
||||||
|
*/
|
||||||
|
/*fclose(fl->fp); - unsafe */
|
||||||
|
close(fileno(fl->fp));
|
||||||
|
fl = fl->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void fclose_and_forget(FILE *fp)
|
||||||
|
{
|
||||||
|
struct FILE_list **pp = &G.FILE_list;
|
||||||
|
while (*pp) {
|
||||||
|
struct FILE_list *cur = *pp;
|
||||||
|
if (cur->fp == fp) {
|
||||||
|
*pp = cur->next;
|
||||||
|
free(cur);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp = &cur->next;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define fclose_and_forget(fp) fclose(fp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Helpers for setting new $n and restoring them back
|
/* Helpers for setting new $n and restoring them back
|
||||||
*/
|
*/
|
||||||
typedef struct save_arg_t {
|
typedef struct save_arg_t {
|
||||||
@ -6276,8 +6334,7 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
|
|||||||
free(to_free);
|
free(to_free);
|
||||||
# endif
|
# endif
|
||||||
close(channel[1]);
|
close(channel[1]);
|
||||||
close_on_exec_on(channel[0]);
|
return remember_FILE(xfdopen_for_read(channel[0]));
|
||||||
return xfdopen_for_read(channel[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ORCAC__
|
#ifdef __ORCAC__
|
||||||
@ -6392,7 +6449,7 @@ static int process_command_subs(o_string *dest, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug_printf(("done reading from `cmd` pipe, closing it\n"));
|
debug_printf(("done reading from `cmd` pipe, closing it\n"));
|
||||||
fclose(fp);
|
fclose_and_forget(fp);
|
||||||
/* We need to extract exitcode. Test case
|
/* We need to extract exitcode. Test case
|
||||||
* "true; echo `sleep 1; false` $?"
|
* "true; echo `sleep 1; false` $?"
|
||||||
* should print 1 */
|
* should print 1 */
|
||||||
@ -7026,6 +7083,8 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
|
|||||||
if (a >= 0) {
|
if (a >= 0) {
|
||||||
# if BB_MMU /* see above why on NOMMU it is not allowed */
|
# if BB_MMU /* see above why on NOMMU it is not allowed */
|
||||||
if (APPLET_IS_NOEXEC(a)) {
|
if (APPLET_IS_NOEXEC(a)) {
|
||||||
|
/* Do not leak open fds from opened script files etc */
|
||||||
|
close_all_FILE_list();
|
||||||
debug_printf_exec(("running applet '%s'\n", argv[0]));
|
debug_printf_exec(("running applet '%s'\n", argv[0]));
|
||||||
run_applet_no_and_exit(a, argv);
|
run_applet_no_and_exit(a, argv);
|
||||||
}
|
}
|
||||||
@ -8486,10 +8545,10 @@ static bool source_startup_file(const char *path)
|
|||||||
{
|
{
|
||||||
FILE *input = fopen_for_read(path);
|
FILE *input = fopen_for_read(path);
|
||||||
if (input != NULL) {
|
if (input != NULL) {
|
||||||
close_on_exec_on(fileno(input));
|
remember_FILE(input);
|
||||||
install_special_sighandlers();
|
install_special_sighandlers();
|
||||||
parse_and_run_file(input);
|
parse_and_run_file(input);
|
||||||
fclose(input);
|
fclose_and_forget(input);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -8875,11 +8934,11 @@ int hush_main(int argc, char **argv)
|
|||||||
G.global_argv++;
|
G.global_argv++;
|
||||||
debug_printf(("running script '%s'\n", G.global_argv[0]));
|
debug_printf(("running script '%s'\n", G.global_argv[0]));
|
||||||
input = xfopen_for_read(G.global_argv[0]);
|
input = xfopen_for_read(G.global_argv[0]);
|
||||||
close_on_exec_on(fileno(input));
|
remember_FILE(input);
|
||||||
install_special_sighandlers();
|
install_special_sighandlers();
|
||||||
parse_and_run_file(input);
|
parse_and_run_file(input);
|
||||||
#if ENABLE_FEATURE_CLEAN_UP
|
#if ENABLE_FEATURE_CLEAN_UP
|
||||||
fclose(input);
|
fclose_and_forget(input);
|
||||||
#endif
|
#endif
|
||||||
goto final_return;
|
goto final_return;
|
||||||
}
|
}
|
||||||
@ -9792,7 +9851,7 @@ static int FAST_FUNC builtin_source(char **argv)
|
|||||||
if (arg_path)
|
if (arg_path)
|
||||||
filename = arg_path;
|
filename = arg_path;
|
||||||
}
|
}
|
||||||
input = fopen_or_warn(filename, "r");
|
input = remember_FILE(fopen_or_warn(filename, "r"));
|
||||||
free(arg_path);
|
free(arg_path);
|
||||||
if (!input) {
|
if (!input) {
|
||||||
/* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
|
/* bb_perror_msg("%s", *argv); - done by fopen_or_warn */
|
||||||
@ -9801,7 +9860,6 @@ static int FAST_FUNC builtin_source(char **argv)
|
|||||||
*/
|
*/
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
close_on_exec_on(fileno(input));
|
|
||||||
|
|
||||||
#if ENABLE_HUSH_FUNCTIONS
|
#if ENABLE_HUSH_FUNCTIONS
|
||||||
sv_flg = G.flag_return_in_progress;
|
sv_flg = G.flag_return_in_progress;
|
||||||
@ -9812,7 +9870,7 @@ static int FAST_FUNC builtin_source(char **argv)
|
|||||||
save_and_replace_G_args(&sv, argv);
|
save_and_replace_G_args(&sv, argv);
|
||||||
|
|
||||||
parse_and_run_file(input);
|
parse_and_run_file(input);
|
||||||
fclose(input);
|
fclose_and_forget(input);
|
||||||
|
|
||||||
if (argv[1])
|
if (argv[1])
|
||||||
restore_G_args(&sv, argv);
|
restore_G_args(&sv, argv);
|
||||||
|
Loading…
Reference in New Issue
Block a user