aboutsummaryrefslogtreecommitdiff
path: root/win32/process.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-02-26 20:39:23 +0000
committerRon Yorston <rmy@pobox.com>2018-02-26 20:39:23 +0000
commit650f67507f2718dec0d4282afea619cfe7a53305 (patch)
tree82e523133f961e8337f42765307b63dc737f2580 /win32/process.c
parentfcb5c968bef6c4fd234e000aaeaa160ac1d16f11 (diff)
downloadbusybox-w32-650f67507f2718dec0d4282afea619cfe7a53305.tar.gz
busybox-w32-650f67507f2718dec0d4282afea619cfe7a53305.tar.bz2
busybox-w32-650f67507f2718dec0d4282afea619cfe7a53305.zip
win32: move detection of file formats to stat(2)
Move the code to detect shell scripts and binary executables from mingw_access to a separate function, has_exec_format. Call this function in do_lstat to decide whether to set the executable bits in the file mode. This will slow down stat but has a couple of advantages: - shell scripts are highlighted in ls output - the test applet can use stat(2) to detect executable files The new function is used to handle another corner case in spawnveq: binary executables without the usual .exe extension are only run by spawnve if the file name ends with '.'. Two minor changes: - file_is_win32_executable has been renamed add_win32_extension to clarify what it does - a call to file_is_executable has been removed from find_command in ash as it resulted in unhelpful error messages.
Diffstat (limited to 'win32/process.c')
-rw-r--r--win32/process.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/win32/process.c b/win32/process.c
index da83d1c96..eda143e0e 100644
--- a/win32/process.c
+++ b/win32/process.c
@@ -192,6 +192,7 @@ static intptr_t
192spawnveq(int mode, const char *path, char *const *argv, char *const *env) 192spawnveq(int mode, const char *path, char *const *argv, char *const *env)
193{ 193{
194 char **new_argv; 194 char **new_argv;
195 char *new_path = NULL;
195 int i, argc = -1; 196 int i, argc = -1;
196 intptr_t ret; 197 intptr_t ret;
197 198
@@ -214,7 +215,7 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env)
214 p = strdup(new_argv[0]); 215 p = strdup(new_argv[0]);
215 } 216 }
216 else { 217 else {
217 p = file_is_win32_executable(new_argv[0]); 218 p = add_win32_extension(new_argv[0]);
218 } 219 }
219 220
220 if (p != NULL && has_bat_suffix(p)) { 221 if (p != NULL && has_bat_suffix(p)) {
@@ -231,12 +232,25 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env)
231 } 232 }
232 } 233 }
233 234
234 ret = spawnve(mode, path, new_argv, env); 235 /*
236 * Another special case: if a binary executable doesn't have an
237 * extension spawnve will only run it if the filename ends with a '.'.
238 */
239 if (!has_exe_suffix(path)) {
240 int len = strlen(path);
241
242 if (path[len-1] != '.' && has_exec_format(path)) {
243 new_path = xasprintf("%s.", path);
244 }
245 }
246
247 ret = spawnve(mode, new_path ? new_path : path, new_argv, env);
235 248
236 for (i = 0;i < argc;i++) 249 for (i = 0;i < argc;i++)
237 if (new_argv[i] != argv[i]) 250 if (new_argv[i] != argv[i])
238 free(new_argv[i]); 251 free(new_argv[i]);
239 free(new_argv); 252 free(new_argv);
253 free(new_path);
240 254
241 return ret; 255 return ret;
242} 256}
@@ -275,7 +289,7 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con
275 memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); 289 memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc);
276 290
277 if (file_is_executable(int_path) || 291 if (file_is_executable(int_path) ||
278 (fullpath=file_is_win32_executable(int_path)) != NULL) { 292 (fullpath=add_win32_extension(int_path)) != NULL) {
279 new_argv[0] = fullpath ? fullpath : int_path; 293 new_argv[0] = fullpath ? fullpath : int_path;
280 ret = spawnveq(mode, new_argv[0], new_argv, envp); 294 ret = spawnveq(mode, new_argv[0], new_argv, envp);
281 } else 295 } else