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 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 }
... ...