From 184edf9bd672bc93856157098d528eab48948ba9 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 16 Mar 2023 10:47:09 +0000 Subject: win32: code shrink detection of executables Add a function, file_is_win32_exe(), to detect if a path refers to an executable. It tries adding extensions if necessary. Use this in a number of places to replace common code of the form path = alloc_ext_space(cmd); if (add_win32_extension(path) || file_is_executable(path)) Saves 32-48 bytes. --- debianutils/which.c | 11 ++++------- include/mingw.h | 3 ++- libbb/executable.c | 10 ++++++---- win32/mingw.c | 34 +++++++++++++++++++++++++--------- win32/process.c | 11 ++++------- 5 files changed, 41 insertions(+), 28 deletions(-) diff --git a/debianutils/which.c b/debianutils/which.c index b2cd4de18..4af6daf4f 100644 --- a/debianutils/which.c +++ b/debianutils/which.c @@ -12,9 +12,8 @@ //config: which is used to find programs in your PATH and //config: print out their pathnames. -// NOTE: For WIN32 this applet is NOEXEC as alloc_ext_space() and -// find_executable() both allocate memory. And find_executable() -// calls alloc_ext_space(). +// NOTE: For WIN32 this applet is NOEXEC as file_is_win32_exe() and +// find_executable() both allocate memory. //applet:IF_PLATFORM_MINGW32(IF_WHICH(APPLET_NOEXEC(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which))) //applet:IF_PLATFORM_POSIX(IF_WHICH(APPLET_NOFORK(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which))) @@ -87,9 +86,9 @@ int which_main(int argc UNUSED_PARAM, char **argv) } #else if (has_path(*argv)) { - char *path = alloc_ext_space(*argv); + char *path = file_is_win32_exe(*argv); - if (add_win32_extension(path) || file_is_executable(path)) { + if (path) { missing = 0; puts(bs_to_slash(path)); } @@ -103,11 +102,9 @@ int which_main(int argc UNUSED_PARAM, char **argv) # endif { argv[0] = (char *)name; - free(path); goto try_PATH; } } - free(path); #endif } else { char *path; diff --git a/include/mingw.h b/include/mingw.h index e49483307..7e6109f2e 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -559,7 +559,9 @@ void init_codepage(void); int has_bat_suffix(const char *p); int has_exe_suffix(const char *p); int has_exe_suffix_or_dot(const char *name); +char *alloc_ext_space(const char *path); int add_win32_extension(char *p); +char *file_is_win32_exe(const char *name); char *bs_to_slash(char *p) FAST_FUNC; void slash_to_bs(char *p) FAST_FUNC; @@ -578,7 +580,6 @@ int unc_root_len(const char *dir); int root_len(const char *path); const char *get_system_drive(void); const char *need_system_drive(const char *path); -char *alloc_ext_space(const char *path); int chdir_system_drive(void); char *xabsolute_path(char *path); char *get_drive_cwd(const char *path, char *buffer, int size); diff --git a/libbb/executable.c b/libbb/executable.c index 770aedc0c..606bec986 100644 --- a/libbb/executable.c +++ b/libbb/executable.c @@ -57,10 +57,12 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp) ); #if ENABLE_PLATFORM_MINGW32 { - char *w = alloc_ext_space(p); - ex = add_win32_extension(w) || file_is_executable(w); - free(p); - p = w; + char *w = file_is_win32_exe(p); + ex = w != NULL; + if (ex) { + free(p); + p = w; + } } #else ex = file_is_executable(p); diff --git a/win32/mingw.c b/win32/mingw.c index c7eeea088..0a1af6b72 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -2001,6 +2001,15 @@ int has_exe_suffix_or_dot(const char *name) return last_char_is(name, '.') || has_win_suffix(name, 0); } +/* Copy path to an allocated string long enough to allow a file extension + * to be added. */ +char *alloc_ext_space(const char *path) +{ + char *s = xmalloc(strlen(path) + 5); + strcpy(s, path); + return s; +} + /* Check if path can be made into an executable by adding a suffix. * The suffix is added to the end of the argument which must be * long enough to allow this. @@ -2024,6 +2033,22 @@ int add_win32_extension(char *p) return FALSE; } +/* + * Determine if a path represents a WIN32 executable, adding a suffix + * if necessary. Returns an allocated string if it does, NULL if not. + */ +char * +file_is_win32_exe(const char *name) +{ + char *path = alloc_ext_space(name); + + if ((add_win32_extension(path) || file_is_executable(path))) + return path; + + free(path); + return NULL; +} + char * FAST_FUNC bs_to_slash(char *str) { char *p; @@ -2193,15 +2218,6 @@ const char *need_system_drive(const char *path) return NULL; } -/* Copy path to an allocated string long enough to allow a file extension - * to be added. */ -char *alloc_ext_space(const char *path) -{ - char *s = xmalloc(strlen(path) + 5); - strcpy(s, path); - return s; -} - int chdir_system_drive(void) { const char *sd = get_system_drive(); diff --git a/win32/process.c b/win32/process.c index 0585f66a6..a0678f50d 100644 --- a/win32/process.c +++ b/win32/process.c @@ -328,14 +328,12 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, } #endif - path = alloc_ext_space(interp.path); - if ((add_win32_extension(path) || file_is_executable(path))) { + path = file_is_win32_exe(interp.path); + if (path) { new_argv[0] = path; ret = mingw_spawn_interpreter(mode, path, new_argv, envp, level); goto done; } - free(path); - path = NULL; if (unix_path(interp.path)) { if ((path = find_first_executable(interp.name)) != NULL) { @@ -363,13 +361,12 @@ mingw_spawnvp(int mode, const char *cmd, char *const *argv) return mingw_spawn_applet(mode, argv, NULL); #endif if (has_path(cmd)) { - path = alloc_ext_space(cmd); - if (add_win32_extension(path) || file_is_executable(path)) { + path = file_is_win32_exe(cmd); + if (path) { ret = mingw_spawn_interpreter(mode, path, argv, NULL, 0); free(path); return ret; } - free(path); if (unix_path(cmd)) cmd = bb_basename(cmd); } -- cgit v1.2.3-55-g6feb