aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-04-17 11:42:11 +0100
committerRon Yorston <rmy@pobox.com>2012-04-17 11:42:11 +0100
commit8c77ef82b5e6e8c53b9d0103ae182587d5088ced (patch)
treeee4cf19b9b0e59f1d0c67b20d76d6a9b96c5ab58 /win32
parent1d1f787a7c2864149d037681badd196b363a3503 (diff)
downloadbusybox-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.c74
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
33static const char * 35static const char *
34parse_interpreter(const char *cmd) 36parse_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
179mingw_spawn_interpreter(int mode, const char *prog, const char *const *argv, const char *const *envp) 205mingw_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