aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-04-06 09:52:32 +0200
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-04-20 19:14:31 +0200
commitbcc67bed4aef285cb07396a2d1a8b87e4ec28fea (patch)
tree3cfd733eaef5b25d0c903f9b678ce8bc10faafab
parent3ad9f036e14f328e79b6f06fc4f9b39bb29b2747 (diff)
downloadbusybox-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.c151
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 */
35static char **
36get_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
72static void
73free_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 */
88static char *
89lookup_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 */
107static char *
108path_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
130static const char * 32static const char *
131parse_interpreter(const char *cmd) 33parse_interpreter(const char *cmd)
132{ 34{
@@ -274,15 +176,15 @@ mingw_spawn_applet(int mode,
274} 176}
275 177
276static pid_t 178static pid_t
277mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, char **path, const char *const *envp) 179mingw_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
311pid_t 214pid_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)
344int 253int
345mingw_execvp(const char *cmd, const char *const *argv) 254mingw_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;