From 9906faf2dff6fd9033cb711619528501cae11721 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 6 Dec 2018 15:16:49 +0000 Subject: win32: rework adding of extensions to filenames Previously there was one function to handle adding extensions to executable filenames, add_win32_extension(). Refactor this into three functions: add_win32_extension() appends the suffix to the argument string in-place. The argument must be long enough to cope with this, as is the case in ash where path_advance() adds 4 bytes to each filename for just this reason. alloc_win32_extension() is equivalent to the old add_win32_extension(). It allocates a string to hold the new filename then calls the new add_win32_extension() function. The caller is responsible for managing the returned string. auto_win32_extension() calls alloc_win32_extension() and saves the resulting string using auto_string(). It's used where the new filename is consumed immediately or the actual value isn't needed. Rewrite code to use the most appropriate function. Also reorder some code in find_executable() and find_command(). --- win32/mingw.c | 52 ++++++++++++++++++++++++++++++++-------------------- win32/process.c | 4 ++-- 2 files changed, 34 insertions(+), 22 deletions(-) (limited to 'win32') diff --git a/win32/mingw.c b/win32/mingw.c index 707e6a3d2..08d955527 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -1160,7 +1160,7 @@ int mingw_rmdir(const char *path) return rmdir(path); } -const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" }; +static const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" }; static int has_win_suffix(const char *name, int start) { @@ -1191,33 +1191,45 @@ int has_exe_suffix_or_dot(const char *name) return last_char_is(name, '.') || has_win_suffix(name, 0); } -/* check if path can be made into an executable by adding a suffix; - * return an allocated string containing the path if it can; - * return NULL if not. +/* 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. * - * if path already has a suffix don't even bother trying + * If the return value is TRUE the argument contains the new path, + * if FALSE the argument is unchanged. */ -char *add_win32_extension(const char *p) +int add_win32_extension(char *p) { - char *path; - int i, len; - - if (has_exe_suffix_or_dot(p)) { - return NULL; + if (!has_exe_suffix_or_dot(p)) { + int i, len = strlen(p); + + p[len] = '.'; + for (i=0; i<4; ++i) { + memcpy(p+len+1, win_suffix[i], 4); + if (file_is_executable(p)) + return TRUE; + } + p[len] = '\0'; } + return FALSE; +} - len = strlen(p); - path = xasprintf("%s.com", p); +/* Check if path can be made into an executable by adding a suffix. + * Return an allocated string containing the path if it can; + * return NULL if not. + * + * If path already has a suffix don't even bother trying. + */ +char *alloc_win32_extension(const char *p) +{ + if (!has_exe_suffix_or_dot(p)) { + int len = strlen(p); + char *path = strcpy(xmalloc(len+5), p); - for (i=0; i<4; ++i) { - memcpy(path+len+1, win_suffix[i], 4); - if (file_is_executable(path)) { + if (add_win32_extension(path)) return path; - } + free(path); } - - free(path); - return NULL; } diff --git a/win32/process.c b/win32/process.c index e9b34b56d..b7f02e431 100644 --- a/win32/process.c +++ b/win32/process.c @@ -240,7 +240,7 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env) p = strdup(new_argv[0]); } else { - p = add_win32_extension(new_argv[0]); + p = alloc_win32_extension(new_argv[0]); } if (p != NULL && has_bat_suffix(p)) { @@ -307,7 +307,7 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con new_argv[nopts+1] = (char *)prog; /* pass absolute path */ memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); - if ((fullpath=add_win32_extension(interp.path)) != NULL || + if ((fullpath=alloc_win32_extension(interp.path)) != NULL || file_is_executable(interp.path)) { new_argv[0] = fullpath ? fullpath : interp.path; ret = spawnveq(mode, new_argv[0], new_argv, envp); -- cgit v1.2.3-55-g6feb