hush: make "test -x" use cached groupinfo
While at it, correct "type" to skip non-executable files in PATH function old new delta builtin_source 211 316 +105 builtin_test 10 32 +22 hush_main 1150 1170 +20 builtin_type 122 137 +15 if_command_vV_print_and_exit 120 114 -6 find_in_path 131 - -131 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 4/1 up/down: 162/-137) Total: 25 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
0929a129fc
commit
baa49bdc1b
1 changed files with 22 additions and 7 deletions
21
shell/hush.c
21
shell/hush.c
|
@ -1021,6 +1021,13 @@ struct globals {
|
|||
#endif
|
||||
#if HUSH_DEBUG >= 2
|
||||
int debug_indent;
|
||||
#endif
|
||||
#if ENABLE_HUSH_TEST || BASH_TEST2
|
||||
/* Cached supplementary group array (for testing executable'ity of files) */
|
||||
struct cached_groupinfo groupinfo;
|
||||
# define GROUPINFO_INIT { G.groupinfo.euid = -1; G.groupinfo.egid = -1; }
|
||||
#else
|
||||
# define GROUPINFO_INIT /* nothing */
|
||||
#endif
|
||||
struct sigaction sa;
|
||||
char optstring_buf[sizeof("eixcs")];
|
||||
|
@ -1040,6 +1047,7 @@ struct globals {
|
|||
/* memset(&G.sa, 0, sizeof(G.sa)); */ \
|
||||
sigfillset(&G.sa.sa_mask); \
|
||||
G.sa.sa_flags = SA_RESTART; \
|
||||
GROUPINFO_INIT; \
|
||||
} while (0)
|
||||
|
||||
/* Function prototypes for builtins */
|
||||
|
@ -8193,6 +8201,8 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Find a file in PATH, not necessarily executable */
|
||||
//TODO: shares code with find_executable() in libbb, factor out?
|
||||
static char *find_in_path(const char *arg)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
@ -8635,7 +8645,7 @@ static void if_command_vV_print_and_exit(char opt_vV, char *cmd, const char *exp
|
|||
|
||||
to_free = NULL;
|
||||
if (!explanation) {
|
||||
char *path = getenv("PATH");
|
||||
char *path = (char*)get_local_var_value("PATH");
|
||||
explanation = to_free = find_executable(cmd, &path); /* path == NULL is ok */
|
||||
if (!explanation)
|
||||
_exit(1); /* PROG was not found */
|
||||
|
@ -10870,7 +10880,8 @@ static NOINLINE int run_applet_main(char **argv, int (*applet_main_func)(int arg
|
|||
#if ENABLE_HUSH_TEST || BASH_TEST2
|
||||
static int FAST_FUNC builtin_test(char **argv)
|
||||
{
|
||||
return run_applet_main(argv, test_main);
|
||||
int argc = string_array_len(argv);
|
||||
return test_main2(&G.groupinfo, argc, argv);
|
||||
}
|
||||
#endif
|
||||
#if ENABLE_HUSH_ECHO
|
||||
|
@ -11063,13 +11074,17 @@ static int FAST_FUNC builtin_type(char **argv)
|
|||
# endif
|
||||
else if (find_builtin(*argv))
|
||||
type = "a shell builtin";
|
||||
else if ((path = find_in_path(*argv)) != NULL)
|
||||
else {
|
||||
char *pathvar = (char*)get_local_var_value("PATH");
|
||||
path = find_executable(*argv, &pathvar);
|
||||
if (path)
|
||||
type = path;
|
||||
else {
|
||||
bb_error_msg("type: %s: not found", *argv);
|
||||
ret = EXIT_FAILURE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s is %s\n", *argv, type);
|
||||
free(path);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue