From d18c624d993b7846fb13053bb7dc7bf1a12770ce Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sat, 20 Jul 2024 10:03:51 +0100 Subject: win32: consolidate executable handling in popen.c Commit f444dc586 (win32: only search PATH for compressor) made mingw_fork_compressor() perform a PATH lookup for the xz and lzma compression programs. This avoided relying on CreateProcess() to perform the search. Other callers of the pipe creation code should also avoid reliance on CreateProcess's executable search: - Move the applet test and PATH lookup into mingw_popen_internal(). The first argument to CreateProcess() will always be a path to an executable. - mingw_fork_compressor() uses the new "w+" mode to indicate that xz and lzma compressors should be found on PATH. - mingw_popen() no longer needs to check for an applet itself, as that's now handled in mingw_popen_internal(). - spawn_ssl_client() in 'wget' can rely on the popen code to look up the 'ssl_client' applet. - Remove unnecessary argument checks in mingw_popen_internal(). Adds 0-24 bytes. --- networking/wget.c | 5 ++--- win32/popen.c | 58 ++++++++++++++++++++++++++----------------------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index f3c0c89f3..b01304897 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -839,12 +839,11 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) fflush_all(); - cmd = xasprintf("%s --busybox ssl_client -h %p -n %s%s", - bb_busybox_exec_path, + cmd = xasprintf("ssl_client -h %p -n %s%s", (void *)_get_osfhandle(network_fd), servername, flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); - if ( (fd1=mingw_popen_fd(NULL, cmd, "b", -1, NULL)) == -1 ) { + if ((fd1=mingw_popen_fd("ssl_client", cmd, "b", -1, NULL)) == -1) { bb_perror_msg_and_die("can't execute ssl_client"); } diff --git a/win32/popen.c b/win32/popen.c index 69c913b70..7cf2b1893 100644 --- a/win32/popen.c +++ b/win32/popen.c @@ -116,7 +116,6 @@ FILE *mingw_popen(const char *cmd, const char *mode) FILE *fptr = NULL; int fd; char *arg, *cmd_buff; - const char *exe = NULL; if ( cmd == NULL || *cmd == '\0' || mode == NULL || (*mode != 'r' && *mode != 'w') ) { @@ -128,16 +127,11 @@ FILE *mingw_popen(const char *cmd, const char *mode) return NULL; } -#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 - if (find_applet_by_name("sh") >= 0) { - exe = bb_busybox_exec_path; - } -#endif arg = quote_arg(cmd); cmd_buff = xasprintf("sh -c %s", arg); /* Create the pipe */ - if ((fd=mingw_popen_internal(p, exe, cmd_buff, mode, -1, NULL)) != -1) { + if ((fd=mingw_popen_internal(p, "sh", cmd_buff, mode, -1, NULL)) != -1) { fptr = _fdopen(fd, *mode == 'r' ? "rb" : "wb"); } @@ -157,6 +151,8 @@ FILE *mingw_popen(const char *cmd, const char *mode) * command ("w"). Otherwise (and if not "b") use stdin or stdout. * - the pid of the command is returned in the variable pid, which * can be NULL if the pid is not required. + * - mode "w+" forces the use of an external program. This is required + * for xz and lzma compression. */ static int mingw_popen_internal(pipe_data *p, const char *exe, const char *cmd, const char *mode, int fd0, pid_t *pid) @@ -166,10 +162,7 @@ static int mingw_popen_internal(pipe_data *p, const char *exe, int success; int fd = -1; int ip, ic, flags; - - if ( cmd == NULL || *cmd == '\0' || mode == NULL ) { - return -1; - } + char *freeme = NULL; switch (*mode) { case 'r': @@ -199,6 +192,20 @@ static int mingw_popen_internal(pipe_data *p, const char *exe, goto finito; } +#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 + // "w+" mode forces a path lookup + if (mode[1] != '+' && find_applet_by_name(exe) >= 0) { + exe = bb_busybox_exec_path; + } else +#endif + { + // Look up executable on PATH + freeme = find_first_executable(exe); + if (freeme == NULL) + bb_perror_msg_and_die("can't execute '%s'", exe); + exe = freeme; + } + /* Make the parent end of the pipe non-inheritable */ SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); @@ -243,6 +250,7 @@ static int mingw_popen_internal(pipe_data *p, const char *exe, fd = _open_osfhandle((intptr_t)p->pipe[ip], flags); finito: + free(freeme); if ( fd == -1 ) { close_pipe_data(p); } @@ -287,34 +295,22 @@ int mingw_pclose(FILE *fp) * file; with mode "r" and a decompressor in open_transformer. */ pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) { - char *cmd, *freeme = NULL; - const char *exe = NULL; + char *cmd; int fd1; pid_t pid; -#if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 - if (find_applet_by_name(compressor) >= 0 -# if ENABLE_XZ || ENABLE_LZMA - /* xz and lzma applets don't support compression, try using - * an external program */ - && !(mode[0] == 'w' && index_in_strings("lzma\0xz\0", compressor) >= 0) -# endif - ) { - exe = bb_busybox_exec_path; - } else { - // Look up compressor on PATH - exe = freeme = find_first_executable(compressor); - if (exe == NULL) - bb_perror_msg_and_die("can't execute '%s'", compressor); - } -#endif cmd = xasprintf("%s -cf -", compressor); +#if ENABLE_FEATURE_SEAMLESS_XZ || ENABLE_FEATURE_SEAMLESS_LZMA + // xz and lzma applets don't support compression, we must use + // an external command. + if (mode[0] == 'w' && index_in_strings("lzma\0xz\0", compressor) >= 0) + mode = "w+"; +#endif - if ((fd1 = mingw_popen_fd(exe, cmd, mode, fd, &pid)) == -1) + if ((fd1 = mingw_popen_fd(compressor, cmd, mode, fd, &pid)) == -1) bb_perror_msg_and_die("can't execute '%s'", compressor); free(cmd); - free(freeme); xmove_fd(fd1, fd); return pid; } -- cgit v1.2.3-55-g6feb