Commit 7d8cec95c84bbfe86462aa048dc62c9e18263015

Authored by aurel32
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,6 +2215,7 @@ static void usage(void)
2215 "-drop-ld-preload drop LD_PRELOAD for target process\n" 2215 "-drop-ld-preload drop LD_PRELOAD for target process\n"
2216 "-E var=value sets/modifies targets environment variable(s)\n" 2216 "-E var=value sets/modifies targets environment variable(s)\n"
2217 "-U var unsets targets environment variable(s)\n" 2217 "-U var unsets targets environment variable(s)\n"
  2218 + "-0 argv0 forces target process argv[0] to be argv0\n"
2218 "\n" 2219 "\n"
2219 "Debug options:\n" 2220 "Debug options:\n"
2220 "-d options activate log (logfile=%s)\n" 2221 "-d options activate log (logfile=%s)\n"
@@ -2266,7 +2267,11 @@ int main(int argc, char **argv, char **envp) @@ -2266,7 +2267,11 @@ int main(int argc, char **argv, char **envp)
2266 const char *r; 2267 const char *r;
2267 int gdbstub_port = 0; 2268 int gdbstub_port = 0;
2268 char **target_environ, **wrk; 2269 char **target_environ, **wrk;
  2270 + char **target_argv;
  2271 + int target_argc;
2269 envlist_t *envlist = NULL; 2272 envlist_t *envlist = NULL;
  2273 + const char *argv0 = NULL;
  2274 + int i;
2270 2275
2271 if (argc <= 1) 2276 if (argc <= 1)
2272 usage(); 2277 usage();
@@ -2323,6 +2328,9 @@ int main(int argc, char **argv, char **envp) @@ -2323,6 +2328,9 @@ int main(int argc, char **argv, char **envp)
2323 r = argv[optind++]; 2328 r = argv[optind++];
2324 if (envlist_unsetenv(envlist, r) != 0) 2329 if (envlist_unsetenv(envlist, r) != 0)
2325 usage(); 2330 usage();
  2331 + } else if (!strcmp(r, "0")) {
  2332 + r = argv[optind++];
  2333 + argv0 = r;
2326 } else if (!strcmp(r, "s")) { 2334 } else if (!strcmp(r, "s")) {
2327 if (optind >= argc) 2335 if (optind >= argc)
2328 break; 2336 break;
@@ -2435,11 +2443,39 @@ int main(int argc, char **argv, char **envp) @@ -2435,11 +2443,39 @@ int main(int argc, char **argv, char **envp)
2435 target_environ = envlist_to_environ(envlist, NULL); 2443 target_environ = envlist_to_environ(envlist, NULL);
2436 envlist_free(envlist); 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 printf("Error loading %s\n", filename); 2470 printf("Error loading %s\n", filename);
2440 _exit(1); 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 for (wrk = target_environ; *wrk; wrk++) { 2479 for (wrk = target_environ; *wrk; wrk++) {
2444 free(*wrk); 2480 free(*wrk);
2445 } 2481 }