aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-07-20 10:03:51 +0100
committerRon Yorston <rmy@pobox.com>2024-07-20 10:31:49 +0100
commitd18c624d993b7846fb13053bb7dc7bf1a12770ce (patch)
tree8d6ca12835230eb552375c2541f65ff4bf7ffc46
parent640ac19cd76573a307d39e06bc3d22a38194a76f (diff)
downloadbusybox-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.c5
-rw-r--r--win32/popen.c58
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 */
161static int mingw_popen_internal(pipe_data *p, const char *exe, 157static 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
245finito: 252finito:
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. */
288pid_t mingw_fork_compressor(int fd, const char *compressor, const char *mode) 296pid_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}