aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
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++)