aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/process.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/win32/process.c b/win32/process.c
index eda143e0e..96561c482 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -195,6 +195,23 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env)
195 char *new_path = NULL; 195 char *new_path = NULL;
196 int i, argc = -1; 196 int i, argc = -1;
197 intptr_t ret; 197 intptr_t ret;
198 struct stat st;
199
200 /*
201 * Require that the file exists, is a regular file and is executable.
202 * It may still contain garbage but we let spawnve deal with that.
203 */
204 if (stat(path, &st) == 0) {
205 if (!S_ISREG(st.st_mode) || !(st.st_mode&S_IXUSR)) {
206 errno = EACCES;
207 fprintf(stderr, "spawnveq: %s: %s\n", path, strerror(errno));
208 return -1;
209 }
210 }
211 else {
212 fprintf(stderr, "spawnveq: %s: %s\n", path, strerror(errno));
213 return -1;
214 }
198 215
199 while (argv[++argc]) 216 while (argv[++argc])
200 ; 217 ;
@@ -233,15 +250,12 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env)
233 } 250 }
234 251
235 /* 252 /*
236 * Another special case: if a binary executable doesn't have an 253 * Another special case: if a file doesn't have an extension add
237 * extension spawnve will only run it if the filename ends with a '.'. 254 * a '.' at the end. This forces spawnve to use precisely the
255 * file specified without trying to add an extension.
238 */ 256 */
239 if (!has_exe_suffix(path)) { 257 if (!strchr(bb_basename(path), '.')) {
240 int len = strlen(path); 258 new_path = xasprintf("%s.", path);
241
242 if (path[len-1] != '.' && has_exec_format(path)) {
243 new_path = xasprintf("%s.", path);
244 }
245 } 259 }
246 260
247 ret = spawnve(mode, new_path ? new_path : path, new_argv, env); 261 ret = spawnve(mode, new_path ? new_path : path, new_argv, env);
@@ -288,8 +302,8 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con
288 new_argv[nopts+1] = (char *)prog; /* pass absolute path */ 302 new_argv[nopts+1] = (char *)prog; /* pass absolute path */
289 memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); 303 memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc);
290 304
291 if (file_is_executable(int_path) || 305 if ((fullpath=add_win32_extension(int_path)) != NULL ||
292 (fullpath=add_win32_extension(int_path)) != NULL) { 306 file_is_executable(int_path)) {
293 new_argv[0] = fullpath ? fullpath : int_path; 307 new_argv[0] = fullpath ? fullpath : int_path;
294 ret = spawnveq(mode, new_argv[0], new_argv, envp); 308 ret = spawnveq(mode, new_argv[0], new_argv, envp);
295 } else 309 } else