diff options
author | Ron Yorston <rmy@pobox.com> | 2012-04-17 11:42:11 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-04-17 11:42:11 +0100 |
commit | 8c77ef82b5e6e8c53b9d0103ae182587d5088ced (patch) | |
tree | ee4cf19b9b0e59f1d0c67b20d76d6a9b96c5ab58 /win32 | |
parent | 1d1f787a7c2864149d037681badd196b363a3503 (diff) | |
download | busybox-w32-8c77ef82b5e6e8c53b9d0103ae182587d5088ced.tar.gz busybox-w32-8c77ef82b5e6e8c53b9d0103ae182587d5088ced.tar.bz2 busybox-w32-8c77ef82b5e6e8c53b9d0103ae182587d5088ced.zip |
Detect and execute shell scripts based on presence of '#!'
Diffstat (limited to 'win32')
-rw-r--r-- | win32/process.c | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/win32/process.c b/win32/process.c index 3ce152c45..2cfec4fdf 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -30,13 +30,18 @@ next_path_sep(const char *path) | |||
30 | return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); | 30 | return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); |
31 | } | 31 | } |
32 | 32 | ||
33 | #define MAX_OPT 10 | ||
34 | |||
33 | static const char * | 35 | static const char * |
34 | parse_interpreter(const char *cmd) | 36 | parse_interpreter(const char *cmd, char ***opts, int *nopts) |
35 | { | 37 | { |
36 | static char buf[100]; | 38 | static char buf[100]; |
37 | char *p, *opt; | 39 | char *p, *s, *t, *opt[MAX_OPT]; |
38 | int n, fd; | 40 | int n, fd; |
39 | 41 | ||
42 | *nopts = 0; | ||
43 | *opts = opt; | ||
44 | |||
40 | /* don't even try a .exe */ | 45 | /* don't even try a .exe */ |
41 | n = strlen(cmd); | 46 | n = strlen(cmd); |
42 | if (n >= 4 && | 47 | if (n >= 4 && |
@@ -58,13 +63,34 @@ parse_interpreter(const char *cmd) | |||
58 | p = strchr(buf, '\n'); | 63 | p = strchr(buf, '\n'); |
59 | if (!p) | 64 | if (!p) |
60 | return NULL; | 65 | return NULL; |
61 | |||
62 | *p = '\0'; | 66 | *p = '\0'; |
67 | |||
68 | /* remove trailing whitespace */ | ||
69 | while ( isspace(*--p) ) { | ||
70 | *p = '\0'; | ||
71 | } | ||
72 | |||
63 | if (!(p = strrchr(buf+2, '/')) && !(p = strrchr(buf+2, '\\'))) | 73 | if (!(p = strrchr(buf+2, '/')) && !(p = strrchr(buf+2, '\\'))) |
64 | return NULL; | 74 | return NULL; |
65 | /* strip options */ | 75 | |
66 | if ((opt = strchr(p+1, ' '))) | 76 | /* move to end of interpreter name */ |
67 | *opt = '\0'; | 77 | for ( s=p; *s && !isspace(*s); ++s ) { |
78 | } | ||
79 | |||
80 | n = 0; | ||
81 | if ( *s != '\0' ) { | ||
82 | /* there are options */ | ||
83 | *s++ = '\0'; | ||
84 | |||
85 | while ( (t=strtok(s, " \t")) && n < MAX_OPT ) { | ||
86 | s = NULL; | ||
87 | opt[n++] = t; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | *nopts = n; | ||
92 | *opts = opt; | ||
93 | |||
68 | return p+1; | 94 | return p+1; |
69 | } | 95 | } |
70 | 96 | ||
@@ -179,35 +205,43 @@ static pid_t | |||
179 | mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, const char *const *envp) | 205 | mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, const char *const *envp) |
180 | { | 206 | { |
181 | int ret; | 207 | int ret; |
182 | const char *interpr = parse_interpreter(prog); | 208 | char **opts; |
209 | int nopts; | ||
210 | const char *interpr = parse_interpreter(prog, &opts, &nopts); | ||
211 | const char **new_argv; | ||
212 | int argc = 0; | ||
183 | 213 | ||
184 | if (!interpr) | 214 | if (!interpr) |
185 | return spawnveq(mode, prog, argv, envp); | 215 | return spawnveq(mode, prog, argv, envp); |
186 | 216 | ||
187 | if (ENABLE_FEATURE_PREFER_APPLETS && !strcmp(interpr, "sh")) { | 217 | |
188 | const char **new_argv; | 218 | while (argv[argc]) |
189 | int argc = 0; | 219 | argc++; |
190 | 220 | new_argv = malloc(sizeof(*argv)*(argc+nopts+2)); | |
191 | while (argv[argc]) | 221 | memcpy(new_argv+1, opts, sizeof(*opts)*nopts); |
192 | argc++; | 222 | memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); |
193 | new_argv = malloc(sizeof(*argv)*(argc+2)); | 223 | new_argv[nopts+1] = prog; /* pass absolute path */ |
194 | memcpy(new_argv+1, argv, sizeof(*argv)*(argc+1)); | 224 | |
195 | new_argv[0] = prog; /* pass absolute path */ | 225 | if (ENABLE_FEATURE_PREFER_APPLETS && find_applet_by_name(interpr) >= 0) { |
196 | ret = mingw_spawn_applet(mode, "sh", new_argv, envp); | 226 | new_argv[0] = interpr; |
197 | free(new_argv); | 227 | ret = mingw_spawn_applet(mode, interpr, new_argv, envp); |
198 | } | 228 | } |
199 | else { | 229 | else { |
200 | char *path = xstrdup(getenv("PATH")); | 230 | char *path = xstrdup(getenv("PATH")); |
201 | char *tmp = path; | 231 | char *tmp = path; |
202 | char *iprog = find_execable(interpr, &tmp); | 232 | char *iprog = find_execable(interpr, &tmp); |
203 | free(path); | 233 | free(path); |
204 | if (!prog) { | 234 | if (!iprog) { |
235 | free(new_argv); | ||
205 | errno = ENOENT; | 236 | errno = ENOENT; |
206 | return -1; | 237 | return -1; |
207 | } | 238 | } |
208 | ret = spawnveq(mode, iprog, argv, envp); | 239 | new_argv[0] = iprog; |
240 | ret = spawnveq(mode, iprog, new_argv, envp); | ||
209 | free(iprog); | 241 | free(iprog); |
210 | } | 242 | } |
243 | |||
244 | free(new_argv); | ||
211 | return ret; | 245 | return ret; |
212 | } | 246 | } |
213 | 247 | ||