diff options
author | Ron Yorston <rmy@pobox.com> | 2019-02-12 08:43:06 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-02-12 08:43:06 +0000 |
commit | 7a8bd5ae33d8c390763f0787afe6b8c495e2d978 (patch) | |
tree | 29b0abb320d73b37f4fa4d9b355b3b32db42e836 /debianutils | |
parent | 0eda390d68c456975289471e68b615ae096ab33b (diff) | |
parent | f81e0120f4478c58e126bcadb19b9954ed184e8f (diff) | |
download | busybox-w32-7a8bd5ae33d8c390763f0787afe6b8c495e2d978.tar.gz busybox-w32-7a8bd5ae33d8c390763f0787afe6b8c495e2d978.tar.bz2 busybox-w32-7a8bd5ae33d8c390763f0787afe6b8c495e2d978.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'debianutils')
-rw-r--r-- | debianutils/start_stop_daemon.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 43b6fca26..3a4c1044a 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -409,7 +409,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
409 | { | 409 | { |
410 | unsigned opt; | 410 | unsigned opt; |
411 | char *signame; | 411 | char *signame; |
412 | char *startas; | 412 | char *startas = NULL; |
413 | char *chuid; | 413 | char *chuid; |
414 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | 414 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY |
415 | // char *retry_arg = NULL; | 415 | // char *retry_arg = NULL; |
@@ -425,10 +425,11 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
425 | /* -K or -S is required; they are mutually exclusive */ | 425 | /* -K or -S is required; they are mutually exclusive */ |
426 | /* -p is required if -m is given */ | 426 | /* -p is required if -m is given */ |
427 | /* -xpun (at least one) is required if -K is given */ | 427 | /* -xpun (at least one) is required if -K is given */ |
428 | /* -xa (at least one) is required if -S is given */ | 428 | // /* -xa (at least one) is required if -S is given */ |
429 | //WRONG: "start-stop-daemon -S -- sleep 5" is a valid invocation | ||
429 | /* -q turns off -v */ | 430 | /* -q turns off -v */ |
430 | "\0" | 431 | "\0" |
431 | "K:S:K--S:S--K:m?p:K?xpun:S?xa" | 432 | "K:S:K--S:S--K:m?p:K?xpun" |
432 | IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"), | 433 | IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"), |
433 | LONGOPTS | 434 | LONGOPTS |
434 | &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile | 435 | &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile |
@@ -442,21 +443,34 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
442 | if (signal_nr < 0) bb_show_usage(); | 443 | if (signal_nr < 0) bb_show_usage(); |
443 | } | 444 | } |
444 | 445 | ||
445 | if (!(opt & OPT_a)) | 446 | //argc -= optind; |
446 | startas = execname; | 447 | argv += optind; |
447 | if (!execname) /* in case -a is given and -x is not */ | 448 | // ARGS contains zeroth arg if -x/-a is not given, else it starts with 1st arg. |
449 | // These will try to execute "[/bin/]sleep 5": | ||
450 | // "start-stop-daemon -S -- sleep 5" | ||
451 | // "start-stop-daemon -S -x /bin/sleep -- 5" | ||
452 | // "start-stop-daemon -S -a sleep -- 5" | ||
453 | // NB: -n option does _not_ behave in this way: this will try to execute "5": | ||
454 | // "start-stop-daemon -S -n sleep -- 5" | ||
455 | if (!execname) { /* -x is not given */ | ||
448 | execname = startas; | 456 | execname = startas; |
449 | if (execname) { | 457 | if (!execname) { /* neither -x nor -a is given */ |
450 | G.execname_sizeof = strlen(execname) + 1; | 458 | execname = argv[0]; |
451 | G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1); | 459 | if (!execname) |
460 | bb_show_usage(); | ||
461 | argv++; | ||
462 | } | ||
452 | } | 463 | } |
464 | if (!startas) /* -a is not given: use -x EXECUTABLE or argv[0] */ | ||
465 | startas = execname; | ||
466 | *--argv = startas; | ||
467 | G.execname_sizeof = strlen(execname) + 1; | ||
468 | G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1); | ||
453 | 469 | ||
454 | // IF_FEATURE_START_STOP_DAEMON_FANCY( | 470 | // IF_FEATURE_START_STOP_DAEMON_FANCY( |
455 | // if (retry_arg) | 471 | // if (retry_arg) |
456 | // retries = xatoi_positive(retry_arg); | 472 | // retries = xatoi_positive(retry_arg); |
457 | // ) | 473 | // ) |
458 | //argc -= optind; | ||
459 | argv += optind; | ||
460 | 474 | ||
461 | if (userspec) { | 475 | if (userspec) { |
462 | user_id = bb_strtou(userspec, NULL, 10); | 476 | user_id = bb_strtou(userspec, NULL, 10); |
@@ -473,7 +487,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
473 | 487 | ||
474 | if (G.found_procs) { | 488 | if (G.found_procs) { |
475 | if (!QUIET) | 489 | if (!QUIET) |
476 | printf("%s is already running\n%u\n", execname, (unsigned)G.found_procs->pid); | 490 | printf("%s is already running\n", execname); |
477 | return !(opt & OPT_OKNODO); | 491 | return !(opt & OPT_OKNODO); |
478 | } | 492 | } |
479 | 493 | ||
@@ -482,30 +496,37 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
482 | xstat(execname, &G.execstat); | 496 | xstat(execname, &G.execstat); |
483 | #endif | 497 | #endif |
484 | 498 | ||
485 | *--argv = startas; | ||
486 | if (opt & OPT_BACKGROUND) { | 499 | if (opt & OPT_BACKGROUND) { |
487 | #if BB_MMU | ||
488 | bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS + DAEMON_DOUBLE_FORK); | ||
489 | /* DAEMON_DEVNULL_STDIO is superfluous - | ||
490 | * it's always done by bb_daemonize() */ | ||
491 | #else | ||
492 | /* Daemons usually call bb_daemonize_or_rexec(), but SSD can do | 500 | /* Daemons usually call bb_daemonize_or_rexec(), but SSD can do |
493 | * without: SSD is not itself a daemon, it _execs_ a daemon. | 501 | * without: SSD is not itself a daemon, it _execs_ a daemon. |
494 | * The usual NOMMU problem of "child can't run indefinitely, | 502 | * The usual NOMMU problem of "child can't run indefinitely, |
495 | * it must exec" does not bite us: we exec anyway. | 503 | * it must exec" does not bite us: we exec anyway. |
504 | * | ||
505 | * bb_daemonize(DAEMON_DEVNULL_STDIO | DAEMON_CLOSE_EXTRA_FDS | DAEMON_DOUBLE_FORK) | ||
506 | * can be used on MMU systems, but use of vfork() | ||
507 | * is preferable since we want to create pidfile | ||
508 | * _before_ parent returns, and vfork() on Linux | ||
509 | * ensures that (by blocking parent until exec in the child). | ||
496 | */ | 510 | */ |
497 | pid_t pid = xvfork(); | 511 | pid_t pid = xvfork(); |
498 | if (pid != 0) { | 512 | if (pid != 0) { |
499 | /* parent */ | 513 | /* Parent */ |
500 | /* why _exit? the child may have changed the stack, | 514 | /* why _exit? the child may have changed the stack, |
501 | * so "return 0" may do bad things */ | 515 | * so "return 0" may do bad things |
516 | */ | ||
502 | _exit(EXIT_SUCCESS); | 517 | _exit(EXIT_SUCCESS); |
503 | } | 518 | } |
504 | /* Child */ | 519 | /* Child */ |
505 | setsid(); /* detach from controlling tty */ | 520 | setsid(); /* detach from controlling tty */ |
506 | /* Redirect stdio to /dev/null, close extra FDs */ | 521 | /* Redirect stdio to /dev/null, close extra FDs */ |
507 | bb_daemon_helper(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS); | 522 | bb_daemon_helper(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS); |
508 | #endif | 523 | /* On Linux, session leader can acquire ctty |
524 | * unknowingly, by opening a tty. | ||
525 | * Prevent this: stop being a session leader. | ||
526 | */ | ||
527 | pid = xvfork(); | ||
528 | if (pid != 0) | ||
529 | _exit(EXIT_SUCCESS); /* Parent */ | ||
509 | } | 530 | } |
510 | if (opt & OPT_MAKEPID) { | 531 | if (opt & OPT_MAKEPID) { |
511 | /* User wants _us_ to make the pidfile */ | 532 | /* User wants _us_ to make the pidfile */ |
@@ -534,6 +555,10 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
534 | } | 555 | } |
535 | } | 556 | } |
536 | #endif | 557 | #endif |
537 | execvp(startas, argv); | 558 | /* Try: |
559 | * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 | ||
560 | * should exec "/bin/usleep", but argv[0] should be "qwerty": | ||
561 | */ | ||
562 | execvp(execname, argv); | ||
538 | bb_perror_msg_and_die("can't execute '%s'", startas); | 563 | bb_perror_msg_and_die("can't execute '%s'", startas); |
539 | } | 564 | } |