diff options
author | Ron Yorston <rmy@pobox.com> | 2024-07-20 10:03:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-07-20 10:31:49 +0100 |
commit | d18c624d993b7846fb13053bb7dc7bf1a12770ce (patch) | |
tree | 8d6ca12835230eb552375c2541f65ff4bf7ffc46 | |
parent | 640ac19cd76573a307d39e06bc3d22a38194a76f (diff) | |
download | busybox-w32-d18c624d993b7846fb13053bb7dc7bf1a12770ce.tar.gz busybox-w32-d18c624d993b7846fb13053bb7dc7bf1a12770ce.tar.bz2 busybox-w32-d18c624d993b7846fb13053bb7dc7bf1a12770ce.zip |
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.
-rw-r--r-- | networking/wget.c | 5 | ||||
-rw-r--r-- | 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) | |||
839 | 839 | ||
840 | fflush_all(); | 840 | fflush_all(); |
841 | 841 | ||
842 | cmd = xasprintf("%s --busybox ssl_client -h %p -n %s%s", | 842 | cmd = xasprintf("ssl_client -h %p -n %s%s", |
843 | bb_busybox_exec_path, | ||
844 | (void *)_get_osfhandle(network_fd), servername, | 843 | (void *)_get_osfhandle(network_fd), servername, |
845 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); | 844 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); |
846 | 845 | ||
847 | if ( (fd1=mingw_popen_fd(NULL, cmd, "b", -1, NULL)) == -1 ) { | 846 | if ((fd1=mingw_popen_fd("ssl_client", cmd, "b", -1, NULL)) == -1) { |
848 | bb_perror_msg_and_die("can't execute ssl_client"); | 847 | bb_perror_msg_and_die("can't execute ssl_client"); |
849 | } | 848 | } |
850 | 849 | ||
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) | |||
116 | FILE *fptr = NULL; | 116 | FILE *fptr = NULL; |
117 | int fd; | 117 | int fd; |
118 | char *arg, *cmd_buff; | 118 | char *arg, *cmd_buff; |
119 | const char *exe = NULL; | ||
120 | 119 | ||
121 | if ( cmd == NULL || *cmd == '\0' || mode == NULL || | 120 | if ( cmd == NULL || *cmd == '\0' || mode == NULL || |
122 | (*mode != 'r' && *mode != 'w') ) { | 121 | (*mode != 'r' && *mode != 'w') ) { |
@@ -128,16 +127,11 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
128 | return NULL; | 127 | return NULL; |
129 | } | 128 | } |
130 | 129 | ||
131 | #if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 | ||
132 | if (find_applet_by_name("sh") >= 0) { | ||
133 | exe = bb_busybox_exec_path; | ||
134 | } | ||
135 | #endif | ||
136 | arg = quote_arg(cmd); | 130 | arg = quote_arg(cmd); |
137 | cmd_buff = xasprintf("sh -c %s", arg); | 131 | cmd_buff = xasprintf("sh -c %s", arg); |
138 | 132 | ||
139 | /* Create the pipe */ | 133 | /* Create the pipe */ |
140 | if ((fd=mingw_popen_internal(p, exe, cmd_buff, mode, -1, NULL)) != -1) { | 134 | if ((fd=mingw_popen_internal(p, "sh", cmd_buff, mode, -1, NULL)) != -1) { |
141 | fptr = _fdopen(fd, *mode == 'r' ? "rb" : "wb"); | 135 | fptr = _fdopen(fd, *mode == 'r' ? "rb" : "wb"); |
142 | } | 136 | } |
143 | 137 | ||
@@ -157,6 +151,8 @@ FILE *mingw_popen(const char *cmd, const char *mode) | |||
157 | * command ("w"). Otherwise (and if not "b") use stdin or stdout. | 151 | * command ("w"). Otherwise (and if not "b") use stdin or stdout. |
158 | * - the pid of the command is returned in the variable pid, which | 152 | * - the pid of the command is returned in the variable pid, which |
159 | * can be NULL if the pid is not required. | 153 | * can be NULL if the pid is not required. |
154 | * - mode "w+" forces the use of an external program. This is required | ||
155 | * for xz and lzma compression. | ||
160 | */ | 156 | */ |
161 | static int mingw_popen_internal(pipe_data *p, const char *exe, | 157 | static int mingw_popen_internal(pipe_data *p, const char *exe, |
162 | const char *cmd, const char *mode, int fd0, pid_t *pid) | 158 | 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, | |||
166 | int success; | 162 | int success; |
167 | int fd = -1; | 163 | int fd = -1; |
168 | int ip, ic, flags; | 164 | int ip, ic, flags; |
169 | 165 | char *freeme = NULL; | |
170 | if ( cmd == NULL || *cmd == '\0' || mode == NULL ) { | ||
171 | return -1; | ||
172 | } | ||
173 | 166 | ||
174 | switch (*mode) { | 167 | switch (*mode) { |
175 | case 'r': | 168 | case 'r': |
@@ -199,6 +192,20 @@ static int mingw_popen_internal(pipe_data *p, const char *exe, | |||
199 | goto finito; | 192 | goto finito; |
200 | } | 193 | } |
201 | 194 | ||
195 | #if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 | ||
196 | // "w+" mode forces a path lookup | ||
197 | if (mode[1] != '+' && find_applet_by_name(exe) >= 0) { | ||
198 | exe = bb_busybox_exec_path; | ||
199 | } else | ||
200 | #endif | ||
201 | { | ||
202 | // Look up executable on PATH | ||
203 | freeme = find_first_executable(exe); | ||
204 | if (freeme == NULL) | ||
205 | bb_perror_msg_and_die("can't execute '%s'", exe); | ||
206 | exe = freeme; | ||
207 | } | ||
208 | |||
202 | /* Make the parent end of the pipe non-inheritable */ | 209 | /* Make the parent end of the pipe non-inheritable */ |
203 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); | 210 | SetHandleInformation(p->pipe[ip], HANDLE_FLAG_INHERIT, 0); |
204 | 211 | ||
@@ -243,6 +250,7 @@ static int mingw_popen_internal(pipe_data *p, const char *exe, | |||
243 | fd = _open_osfhandle((intptr_t)p->pipe[ip], flags); | 250 | fd = _open_osfhandle((intptr_t)p->pipe[ip], flags); |
244 | 251 | ||
245 | finito: | 252 | finito: |
253 | free(freeme); | ||
246 | if ( fd == -1 ) { | 254 | if ( fd == -1 ) { |
247 | close_pipe_data(p); | 255 | close_pipe_data(p); |
248 | } | 256 | } |
@@ -287,34 +295,22 @@ int mingw_pclose(FILE *fp) | |||
287 | * file; with mode "r" and a decompressor in open_transformer. */ | 295 | * file; with mode "r" and a decompressor in open_transformer. */ |
288 | pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) | 296 | pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) |
289 | { | 297 | { |
290 | char *cmd, *freeme = NULL; | 298 | char *cmd; |
291 | const char *exe = NULL; | ||
292 | int fd1; | 299 | int fd1; |
293 | pid_t pid; | 300 | pid_t pid; |
294 | 301 | ||
295 | #if ENABLE_FEATURE_PREFER_APPLETS && NUM_APPLETS > 1 | ||
296 | if (find_applet_by_name(compressor) >= 0 | ||
297 | # if ENABLE_XZ || ENABLE_LZMA | ||
298 | /* xz and lzma applets don't support compression, try using | ||
299 | * an external program */ | ||
300 | && !(mode[0] == 'w' && index_in_strings("lzma\0xz\0", compressor) >= 0) | ||
301 | # endif | ||
302 | ) { | ||
303 | exe = bb_busybox_exec_path; | ||
304 | } else { | ||
305 | // Look up compressor on PATH | ||
306 | exe = freeme = find_first_executable(compressor); | ||
307 | if (exe == NULL) | ||
308 | bb_perror_msg_and_die("can't execute '%s'", compressor); | ||
309 | } | ||
310 | #endif | ||
311 | cmd = xasprintf("%s -cf -", compressor); | 302 | cmd = xasprintf("%s -cf -", compressor); |
303 | #if ENABLE_FEATURE_SEAMLESS_XZ || ENABLE_FEATURE_SEAMLESS_LZMA | ||
304 | // xz and lzma applets don't support compression, we must use | ||
305 | // an external command. | ||
306 | if (mode[0] == 'w' && index_in_strings("lzma\0xz\0", compressor) >= 0) | ||
307 | mode = "w+"; | ||
308 | #endif | ||
312 | 309 | ||
313 | if ((fd1 = mingw_popen_fd(exe, cmd, mode, fd, &pid)) == -1) | 310 | if ((fd1 = mingw_popen_fd(compressor, cmd, mode, fd, &pid)) == -1) |
314 | bb_perror_msg_and_die("can't execute '%s'", compressor); | 311 | bb_perror_msg_and_die("can't execute '%s'", compressor); |
315 | 312 | ||
316 | free(cmd); | 313 | free(cmd); |
317 | free(freeme); | ||
318 | xmove_fd(fd1, fd); | 314 | xmove_fd(fd1, fd); |
319 | return pid; | 315 | return pid; |
320 | } | 316 | } |