diff options
author | Ron Yorston <rmy@pobox.com> | 2018-02-26 10:08:50 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-02-26 10:08:50 +0000 |
commit | 00f2d33f37da42e17e5d978958659c4899cb2f0a (patch) | |
tree | 5d43272aa7c6a4f3be2dd4f9e9d1edf3963ec69d /win32 | |
parent | 7288179d1218f8e0308455d4d58346aec268eb2e (diff) | |
download | busybox-w32-00f2d33f37da42e17e5d978958659c4899cb2f0a.tar.gz busybox-w32-00f2d33f37da42e17e5d978958659c4899cb2f0a.tar.bz2 busybox-w32-00f2d33f37da42e17e5d978958659c4899cb2f0a.zip |
win32: add support for batch files
Support batch files with .bat and .cmd extensions, similar to
what's done for .exe and .com.
Check extensions in the same order as Windows' spawn function:
.com, .exe, .bat, .cmd.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/mingw.c | 43 | ||||
-rw-r--r-- | win32/process.c | 28 |
2 files changed, 59 insertions, 12 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index 86f649674..ad1c3c16f 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -1003,7 +1003,7 @@ int mingw_access(const char *name, int mode) | |||
1003 | 1003 | ||
1004 | if (!mingw_stat(name, &s) && S_ISREG(s.st_mode)) { | 1004 | if (!mingw_stat(name, &s) && S_ISREG(s.st_mode)) { |
1005 | 1005 | ||
1006 | /* stat marks .exe and .com files as executable */ | 1006 | /* stat marks files as executable according to their suffix */ |
1007 | if ((s.st_mode&S_IEXEC)) { | 1007 | if ((s.st_mode&S_IEXEC)) { |
1008 | return 0; | 1008 | return 0; |
1009 | } | 1009 | } |
@@ -1060,12 +1060,30 @@ int mingw_rmdir(const char *path) | |||
1060 | return rmdir(path); | 1060 | return rmdir(path); |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | int has_exe_suffix(const char *name) | 1063 | const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" }; |
1064 | |||
1065 | static int has_win_suffix(const char *name, int start) | ||
1064 | { | 1066 | { |
1065 | int len = strlen(name); | 1067 | int i, len = strlen(name); |
1066 | 1068 | ||
1067 | return len > 4 && (!strcasecmp(name+len-4, ".exe") || | 1069 | if (len > 4) { |
1068 | !strcasecmp(name+len-4, ".com")); | 1070 | for (i=start; i<4; ++i) { |
1071 | if (!strcasecmp(name+len-3, win_suffix[i])) { | ||
1072 | return 1; | ||
1073 | } | ||
1074 | } | ||
1075 | } | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | int has_bat_suffix(const char *name) | ||
1080 | { | ||
1081 | return has_win_suffix(name, 2); | ||
1082 | } | ||
1083 | |||
1084 | int has_exe_suffix(const char *name) | ||
1085 | { | ||
1086 | return has_win_suffix(name, 0); | ||
1069 | } | 1087 | } |
1070 | 1088 | ||
1071 | /* check if path can be made into an executable by adding a suffix; | 1089 | /* check if path can be made into an executable by adding a suffix; |
@@ -1077,19 +1095,20 @@ int has_exe_suffix(const char *name) | |||
1077 | char *file_is_win32_executable(const char *p) | 1095 | char *file_is_win32_executable(const char *p) |
1078 | { | 1096 | { |
1079 | char *path; | 1097 | char *path; |
1098 | int i, len; | ||
1080 | 1099 | ||
1081 | if (has_exe_suffix(p)) { | 1100 | if (has_exe_suffix(p)) { |
1082 | return NULL; | 1101 | return NULL; |
1083 | } | 1102 | } |
1084 | 1103 | ||
1085 | path = xasprintf("%s.exe", p); | 1104 | len = strlen(p); |
1086 | if (file_is_executable(path)) { | 1105 | path = xasprintf("%s.com", p); |
1087 | return path; | ||
1088 | } | ||
1089 | 1106 | ||
1090 | memcpy(path+strlen(p), ".com", 5); | 1107 | for (i=0; i<4; ++i) { |
1091 | if (file_is_executable(path)) { | 1108 | memcpy(path+len+1, win_suffix[i], 4); |
1092 | return path; | 1109 | if (file_is_executable(path)) { |
1110 | return path; | ||
1111 | } | ||
1093 | } | 1112 | } |
1094 | 1113 | ||
1095 | free(path); | 1114 | free(path); |
diff --git a/win32/process.c b/win32/process.c index a0e8b96e0..da83d1c96 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -203,6 +203,34 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env) | |||
203 | new_argv[i] = quote_arg(argv[i]); | 203 | new_argv[i] = quote_arg(argv[i]); |
204 | new_argv[argc] = NULL; | 204 | new_argv[argc] = NULL; |
205 | 205 | ||
206 | /* | ||
207 | * Special case: spawnve won't execute a batch file when the path | ||
208 | * starts with a '.' and contains forward slashes. | ||
209 | */ | ||
210 | if (new_argv[0][0] == '.') { | ||
211 | char *s, *p; | ||
212 | |||
213 | if (has_bat_suffix(new_argv[0])) { | ||
214 | p = strdup(new_argv[0]); | ||
215 | } | ||
216 | else { | ||
217 | p = file_is_win32_executable(new_argv[0]); | ||
218 | } | ||
219 | |||
220 | if (p != NULL && has_bat_suffix(p)) { | ||
221 | for (s=p; *s; ++s) { | ||
222 | if (*s == '/') | ||
223 | *s = '\\'; | ||
224 | } | ||
225 | if (new_argv[0] != argv[0]) | ||
226 | free(new_argv[0]); | ||
227 | new_argv[0] = p; | ||
228 | } | ||
229 | else { | ||
230 | free(p); | ||
231 | } | ||
232 | } | ||
233 | |||
206 | ret = spawnve(mode, path, new_argv, env); | 234 | ret = spawnve(mode, path, new_argv, env); |
207 | 235 | ||
208 | for (i = 0;i < argc;i++) | 236 | for (i = 0;i < argc;i++) |