diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-04-06 09:52:32 +0200 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-04-20 19:14:31 +0200 |
commit | bcc67bed4aef285cb07396a2d1a8b87e4ec28fea (patch) | |
tree | 3cfd733eaef5b25d0c903f9b678ce8bc10faafab | |
parent | 3ad9f036e14f328e79b6f06fc4f9b39bb29b2747 (diff) | |
download | busybox-w32-bcc67bed4aef285cb07396a2d1a8b87e4ec28fea.tar.gz busybox-w32-bcc67bed4aef285cb07396a2d1a8b87e4ec28fea.tar.bz2 busybox-w32-bcc67bed4aef285cb07396a2d1a8b87e4ec28fea.zip |
win32: process.c: use execable.c
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
-rw-r--r-- | win32/process.c | 151 |
1 files changed, 28 insertions, 123 deletions
diff --git a/win32/process.c b/win32/process.c index 5049be030..cdae13f38 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -29,104 +29,6 @@ next_path_sep(const char *path) | |||
29 | return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); | 29 | return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); |
30 | } | 30 | } |
31 | 31 | ||
32 | /* | ||
33 | * Splits the PATH into parts. | ||
34 | */ | ||
35 | static char ** | ||
36 | get_path_split(void) | ||
37 | { | ||
38 | char *p, **path, *envpath = getenv("PATH"); | ||
39 | int i, n = 0; | ||
40 | |||
41 | if (!envpath || !*envpath) | ||
42 | return NULL; | ||
43 | |||
44 | envpath = xstrdup(envpath); | ||
45 | p = envpath; | ||
46 | while (p) { | ||
47 | char *dir = p; | ||
48 | p = strchr(p, ';'); | ||
49 | if (p) *p++ = '\0'; | ||
50 | if (*dir) { /* not earlier, catches series of ; */ | ||
51 | ++n; | ||
52 | } | ||
53 | } | ||
54 | if (!n) | ||
55 | return NULL; | ||
56 | |||
57 | path = xmalloc((n+1)*sizeof(char*)); | ||
58 | p = envpath; | ||
59 | i = 0; | ||
60 | do { | ||
61 | if (*p) | ||
62 | path[i++] = xstrdup(p); | ||
63 | p = p+strlen(p)+1; | ||
64 | } while (i < n); | ||
65 | path[i] = NULL; | ||
66 | |||
67 | free(envpath); | ||
68 | |||
69 | return path; | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | free_path_split(char **path) | ||
74 | { | ||
75 | if (path) { | ||
76 | char **p = path; | ||
77 | |||
78 | while (*p) | ||
79 | free(*p++); | ||
80 | free(path); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * exe_only means that we only want to detect .exe files, but not scripts | ||
86 | * (which do not have an extension) | ||
87 | */ | ||
88 | static char * | ||
89 | lookup_prog(const char *dir, const char *cmd, int isexe, int exe_only) | ||
90 | { | ||
91 | char path[MAX_PATH]; | ||
92 | snprintf(path, sizeof(path), "%s/%s.exe", dir, cmd); | ||
93 | |||
94 | if (!isexe && access(path, F_OK) == 0) | ||
95 | return xstrdup(path); | ||
96 | path[strlen(path)-4] = '\0'; | ||
97 | if ((!exe_only || isexe) && access(path, F_OK) == 0) | ||
98 | if (!(GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY)) | ||
99 | return xstrdup(path); | ||
100 | return NULL; | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * Determines the absolute path of cmd using the the split path in path. | ||
105 | * If cmd contains a slash or backslash, no lookup is performed. | ||
106 | */ | ||
107 | static char * | ||
108 | path_lookup(const char *cmd, char **path, int exe_only) | ||
109 | { | ||
110 | char *prog = NULL; | ||
111 | int len = strlen(cmd); | ||
112 | int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe"); | ||
113 | |||
114 | if (strchr(cmd, '/') || strchr(cmd, '\\')) { | ||
115 | if (!isexe) { | ||
116 | char path_exe[MAX_PATH]; | ||
117 | sprintf(path_exe, "%s.exe", cmd); | ||
118 | if (!access(path_exe, F_OK)) | ||
119 | return xstrdup(path_exe); | ||
120 | } | ||
121 | prog = xstrdup(cmd); | ||
122 | } | ||
123 | |||
124 | while (!prog && *path) | ||
125 | prog = lookup_prog(*path++, cmd, isexe, exe_only); | ||
126 | |||
127 | return prog; | ||
128 | } | ||
129 | |||
130 | static const char * | 32 | static const char * |
131 | parse_interpreter(const char *cmd) | 33 | parse_interpreter(const char *cmd) |
132 | { | 34 | { |
@@ -274,15 +176,15 @@ mingw_spawn_applet(int mode, | |||
274 | } | 176 | } |
275 | 177 | ||
276 | static pid_t | 178 | static pid_t |
277 | mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, char **path, const char *const *envp) | 179 | mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, const char *const *envp) |
278 | { | 180 | { |
181 | int ret; | ||
279 | const char *interpr = parse_interpreter(prog); | 182 | const char *interpr = parse_interpreter(prog); |
280 | 183 | ||
281 | if (!interpr) | 184 | if (!interpr) |
282 | return spawnveq(mode, prog, argv, envp); | 185 | return spawnveq(mode, prog, argv, envp); |
283 | 186 | ||
284 | if (ENABLE_FEATURE_PREFER_APPLETS && !strcmp(interpr, "sh")) { | 187 | if (ENABLE_FEATURE_PREFER_APPLETS && !strcmp(interpr, "sh")) { |
285 | int ret; | ||
286 | const char **new_argv; | 188 | const char **new_argv; |
287 | int argc = 0; | 189 | int argc = 0; |
288 | 190 | ||
@@ -293,19 +195,20 @@ mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, cha | |||
293 | new_argv[0] = prog; /* pass absolute path */ | 195 | new_argv[0] = prog; /* pass absolute path */ |
294 | ret = mingw_spawn_applet(mode, "sh", new_argv, envp, 0); | 196 | ret = mingw_spawn_applet(mode, "sh", new_argv, envp, 0); |
295 | free(new_argv); | 197 | free(new_argv); |
296 | return ret; | ||
297 | } | 198 | } |
298 | else { | 199 | else { |
299 | int ret; | 200 | char *path = xstrdup(getenv("PATH")); |
300 | char *iprog = path_lookup(interpr, path, 1); | 201 | char *tmp = path; |
301 | if (!iprog) { | 202 | char *iprog = find_execable(interpr, &tmp); |
203 | free(path); | ||
204 | if (!prog) { | ||
302 | errno = ENOENT; | 205 | errno = ENOENT; |
303 | return -1; | 206 | return -1; |
304 | } | 207 | } |
305 | ret = spawnveq(mode, iprog, argv, envp); | 208 | ret = spawnveq(mode, iprog, argv, envp); |
306 | free(iprog); | 209 | free(iprog); |
307 | return ret; | ||
308 | } | 210 | } |
211 | return ret; | ||
309 | } | 212 | } |
310 | 213 | ||
311 | pid_t | 214 | pid_t |
@@ -315,22 +218,28 @@ mingw_spawn_1(int mode, const char *cmd, const char *const *argv, const char *co | |||
315 | 218 | ||
316 | if (ENABLE_FEATURE_PREFER_APPLETS && | 219 | if (ENABLE_FEATURE_PREFER_APPLETS && |
317 | find_applet_by_name(cmd) >= 0) | 220 | find_applet_by_name(cmd) >= 0) |
318 | return mingw_spawn_applet(mode, cmd, argv++, envp, 0); | 221 | return mingw_spawn_applet(mode, cmd, argv++, envp); |
222 | else if (is_absolute_path(cmd)) | ||
223 | return mingw_spawn_interpreter(mode, cmd, argv, envp); | ||
319 | else { | 224 | else { |
320 | char **path = get_path_split(); | 225 | char *tmp, *path = getenv("PATH"); |
321 | char *prog = path_lookup(cmd, path, 0); | 226 | char *prog; |
322 | 227 | ||
323 | if (prog) { | 228 | if (!path) { |
324 | ret = mingw_spawn_interpreter(mode, prog, argv, path, envp); | 229 | errno = ENOENT; |
325 | free(prog); | 230 | return -1; |
326 | free_path_split(path); | ||
327 | return ret; | ||
328 | } | 231 | } |
329 | else { | 232 | |
233 | /* exists_execable() does not return new file name */ | ||
234 | tmp = path = xstrdup(path); | ||
235 | prog = find_execable(cmd, &tmp); | ||
236 | free(path); | ||
237 | if (!prog) { | ||
330 | errno = ENOENT; | 238 | errno = ENOENT; |
331 | free_path_split(path); | ||
332 | return -1; | 239 | return -1; |
333 | } | 240 | } |
241 | ret = mingw_spawn_interpreter(mode, prog, argv, envp); | ||
242 | free(prog); | ||
334 | } | 243 | } |
335 | return ret; | 244 | return ret; |
336 | } | 245 | } |
@@ -344,8 +253,7 @@ mingw_spawn(char **argv) | |||
344 | int | 253 | int |
345 | mingw_execvp(const char *cmd, const char *const *argv) | 254 | mingw_execvp(const char *cmd, const char *const *argv) |
346 | { | 255 | { |
347 | int ret = (int)mingw_spawn_1(P_WAIT, cmd, argv, | 256 | int ret = (int)mingw_spawn_1(P_WAIT, cmd, argv, (const char *const *)environ); |
348 | (const char *const *)environ); | ||
349 | if (ret != -1) | 257 | if (ret != -1) |
350 | exit(ret); | 258 | exit(ret); |
351 | return ret; | 259 | return ret; |
@@ -359,12 +267,9 @@ mingw_execve(const char *cmd, const char *const *argv, const char *const *envp) | |||
359 | 267 | ||
360 | if (ENABLE_FEATURE_PREFER_APPLETS && | 268 | if (ENABLE_FEATURE_PREFER_APPLETS && |
361 | find_applet_by_name(cmd) >= 0) | 269 | find_applet_by_name(cmd) >= 0) |
362 | ret = mingw_spawn_applet(mode, cmd, argv++, envp, 0); | 270 | ret = mingw_spawn_applet(mode, cmd, argv++, envp); |
363 | else { | 271 | else |
364 | char **path = get_path_split(); | 272 | ret = mingw_spawn_interpreter(mode, cmd, argv, envp); |
365 | ret = mingw_spawn_interpreter(mode, cmd, argv, path, envp); | ||
366 | free_path_split(path); | ||
367 | } | ||
368 | if (ret != -1) | 273 | if (ret != -1) |
369 | exit(ret); | 274 | exit(ret); |
370 | return ret; | 275 | return ret; |