diff options
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++) |