Commit 7d8cec95c84bbfe86462aa048dc62c9e18263015
1 parent
24e1003a
linux-user: add support for passing contents of argv0
Added switch -0 (zero) which can be used to pass argv[0] to target process. The main use is for a binfmt_misc wrapper when the "P - preserve-argv[0]" setting is used. From: Mika Westerberg Signed-off-by: Riku Voipio <riku.voipio@iki.fi> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7115 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
37 additions
and
1 deletions
linux-user/main.c
| ... | ... | @@ -2215,6 +2215,7 @@ static void usage(void) |
| 2215 | 2215 | "-drop-ld-preload drop LD_PRELOAD for target process\n" |
| 2216 | 2216 | "-E var=value sets/modifies targets environment variable(s)\n" |
| 2217 | 2217 | "-U var unsets targets environment variable(s)\n" |
| 2218 | + "-0 argv0 forces target process argv[0] to be argv0\n" | |
| 2218 | 2219 | "\n" |
| 2219 | 2220 | "Debug options:\n" |
| 2220 | 2221 | "-d options activate log (logfile=%s)\n" |
| ... | ... | @@ -2266,7 +2267,11 @@ int main(int argc, char **argv, char **envp) |
| 2266 | 2267 | const char *r; |
| 2267 | 2268 | int gdbstub_port = 0; |
| 2268 | 2269 | char **target_environ, **wrk; |
| 2270 | + char **target_argv; | |
| 2271 | + int target_argc; | |
| 2269 | 2272 | envlist_t *envlist = NULL; |
| 2273 | + const char *argv0 = NULL; | |
| 2274 | + int i; | |
| 2270 | 2275 | |
| 2271 | 2276 | if (argc <= 1) |
| 2272 | 2277 | usage(); |
| ... | ... | @@ -2323,6 +2328,9 @@ int main(int argc, char **argv, char **envp) |
| 2323 | 2328 | r = argv[optind++]; |
| 2324 | 2329 | if (envlist_unsetenv(envlist, r) != 0) |
| 2325 | 2330 | usage(); |
| 2331 | + } else if (!strcmp(r, "0")) { | |
| 2332 | + r = argv[optind++]; | |
| 2333 | + argv0 = r; | |
| 2326 | 2334 | } else if (!strcmp(r, "s")) { |
| 2327 | 2335 | if (optind >= argc) |
| 2328 | 2336 | break; |
| ... | ... | @@ -2435,11 +2443,39 @@ int main(int argc, char **argv, char **envp) |
| 2435 | 2443 | target_environ = envlist_to_environ(envlist, NULL); |
| 2436 | 2444 | envlist_free(envlist); |
| 2437 | 2445 | |
| 2438 | - if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { | |
| 2446 | + /* | |
| 2447 | + * Prepare copy of argv vector for target. | |
| 2448 | + */ | |
| 2449 | + target_argc = argc - optind; | |
| 2450 | + target_argv = calloc(target_argc + 1, sizeof (char *)); | |
| 2451 | + if (target_argv == NULL) { | |
| 2452 | + (void) fprintf(stderr, "Unable to allocate memory for target_argv\n"); | |
| 2453 | + exit(1); | |
| 2454 | + } | |
| 2455 | + | |
| 2456 | + /* | |
| 2457 | + * If argv0 is specified (using '-0' switch) we replace | |
| 2458 | + * argv[0] pointer with the given one. | |
| 2459 | + */ | |
| 2460 | + i = 0; | |
| 2461 | + if (argv0 != NULL) { | |
| 2462 | + target_argv[i++] = strdup(argv0); | |
| 2463 | + } | |
| 2464 | + for (; i < target_argc; i++) { | |
| 2465 | + target_argv[i] = strdup(argv[optind + i]); | |
| 2466 | + } | |
| 2467 | + target_argv[target_argc] = NULL; | |
| 2468 | + | |
| 2469 | + if (loader_exec(filename, target_argv, target_environ, regs, info) != 0) { | |
| 2439 | 2470 | printf("Error loading %s\n", filename); |
| 2440 | 2471 | _exit(1); |
| 2441 | 2472 | } |
| 2442 | 2473 | |
| 2474 | + for (i = 0; i < target_argc; i++) { | |
| 2475 | + free(target_argv[i]); | |
| 2476 | + } | |
| 2477 | + free(target_argv); | |
| 2478 | + | |
| 2443 | 2479 | for (wrk = target_environ; *wrk; wrk++) { |
| 2444 | 2480 | free(*wrk); |
| 2445 | 2481 | } | ... | ... |