aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-02-26 10:08:50 +0000
committerRon Yorston <rmy@pobox.com>2018-02-26 10:08:50 +0000
commit00f2d33f37da42e17e5d978958659c4899cb2f0a (patch)
tree5d43272aa7c6a4f3be2dd4f9e9d1edf3963ec69d /win32
parent7288179d1218f8e0308455d4d58346aec268eb2e (diff)
downloadbusybox-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.c43
-rw-r--r--win32/process.c28
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
1063int has_exe_suffix(const char *name) 1063const char win_suffix[4][4] = { "com", "exe", "bat", "cmd" };
1064
1065static 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
1079int has_bat_suffix(const char *name)
1080{
1081 return has_win_suffix(name, 2);
1082}
1083
1084int 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)
1077char *file_is_win32_executable(const char *p) 1095char *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++)