Link Here
|
|
|
1 |
--- a/bsd-user/freebsd/os-proc.c |
2 |
--- b/bsd-user/freebsd/os-proc.c |
3 |
@@ -83,7 +83,7 @@ out: |
4 |
} |
5 |
|
6 |
static int |
7 |
-is_target_shell_script(int fd, char *interp, size_t size) |
8 |
+is_target_shell_script(int fd, char *interp, size_t size, char **interp_args) |
9 |
{ |
10 |
char buf[2], *p, *b; |
11 |
ssize_t n; |
12 |
@@ -120,7 +120,21 @@ is_target_shell_script(int fd, char *int |
13 |
return 0; |
14 |
} |
15 |
if ((p = memchr(b, '\n', size)) != NULL) { |
16 |
+ int hasargs = 0; |
17 |
*p = 0; |
18 |
+ |
19 |
+ *interp_args = NULL; |
20 |
+ p = interp; |
21 |
+ while (*p) { |
22 |
+ if ((*p == ' ') || (*p == '\t')) { |
23 |
+ hasargs = 1; |
24 |
+ *p = 0; |
25 |
+ } else if (hasargs) { |
26 |
+ *interp_args = p; |
27 |
+ break; |
28 |
+ } |
29 |
+ ++p; |
30 |
+ } |
31 |
return 1; |
32 |
} |
33 |
b += n; |
34 |
@@ -136,7 +150,7 @@ is_target_shell_script(int fd, char *int |
35 |
abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, |
36 |
abi_ulong guest_envp, int do_fexec) |
37 |
{ |
38 |
- char **argp, **envp, **qargp, **qarg1, **qarg0; |
39 |
+ char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend; |
40 |
int argc, envc; |
41 |
abi_ulong gp; |
42 |
abi_ulong addr; |
43 |
@@ -166,7 +180,7 @@ abi_long freebsd_exec_common(abi_ulong p |
44 |
envc++; |
45 |
} |
46 |
|
47 |
- qarg0 = argp = alloca((argc + 4) * sizeof(void *)); |
48 |
+ qarg0 = argp = alloca((argc + 5) * sizeof(void *)); |
49 |
/* save the first agrument for the emulator */ |
50 |
*argp++ = (char *)getprogname(); |
51 |
qargp = argp; |
52 |
@@ -188,7 +202,8 @@ abi_long freebsd_exec_common(abi_ulong p |
53 |
} |
54 |
total_size += strlen(*q) + 1; |
55 |
} |
56 |
- *q = NULL; |
57 |
+ *q++ = NULL; |
58 |
+ qargend = q; |
59 |
|
60 |
for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { |
61 |
if (get_user_ual(addr, gp)) { |
62 |
@@ -217,7 +232,7 @@ abi_long freebsd_exec_common(abi_ulong p |
63 |
} |
64 |
|
65 |
if (do_fexec) { |
66 |
- char execpath[PATH_MAX]; |
67 |
+ char execpath[PATH_MAX], *scriptargs; |
68 |
|
69 |
if (((int)path_or_fd > 0 && |
70 |
is_target_elf_binary((int)path_or_fd)) == 1) { |
71 |
@@ -238,7 +253,7 @@ abi_long freebsd_exec_common(abi_ulong p |
72 |
goto execve_end; |
73 |
} |
74 |
} else if (is_target_shell_script((int)path_or_fd, execpath, |
75 |
- sizeof(execpath)) != 0) { |
76 |
+ sizeof(execpath), &scriptargs) != 0) { |
77 |
char scriptpath[PATH_MAX]; |
78 |
|
79 |
/* execve() as a target script using emulator. */ |
80 |
@@ -246,6 +261,10 @@ abi_long freebsd_exec_common(abi_ulong p |
81 |
sizeof(scriptpath)) != NULL) { |
82 |
*qargp = execpath; |
83 |
*qarg1 = scriptpath; |
84 |
+ if (scriptargs) { |
85 |
+ memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); |
86 |
+ *qarg1 = scriptargs; |
87 |
+ } |
88 |
ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); |
89 |
} else { |
90 |
ret = -TARGET_EBADF; |
91 |
@@ -256,7 +275,7 @@ abi_long freebsd_exec_common(abi_ulong p |
92 |
} |
93 |
} else { |
94 |
int fd; |
95 |
- char execpath[PATH_MAX]; |
96 |
+ char execpath[PATH_MAX], *scriptargs; |
97 |
|
98 |
p = lock_user_string(path_or_fd); |
99 |
if (p == NULL) { |
100 |
@@ -275,11 +294,15 @@ abi_long freebsd_exec_common(abi_ulong p |
101 |
*qarg1 = (char *)p; |
102 |
ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); |
103 |
} else if (is_target_shell_script(fd, execpath, |
104 |
- sizeof(execpath)) != 0) { |
105 |
+ sizeof(execpath), &scriptargs) != 0) { |
106 |
close(fd); |
107 |
/* execve() as a target script using emulator. */ |
108 |
*qargp = execpath; |
109 |
*qarg1 = (char *)p; |
110 |
+ if (scriptargs) { |
111 |
+ memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); |
112 |
+ *qarg1 = scriptargs; |
113 |
+ } |
114 |
ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); |
115 |
} else { |
116 |
close(fd); |