diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-11-08 14:07:20 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-11-08 14:07:20 +0100 |
| commit | 58ca629fd27cd9d7f91a8ea90435cdb3f15381aa (patch) | |
| tree | 6cd26e1bd56e7eed350ff8fa3d4aeecf58ef3a22 /debianutils | |
| parent | 2de67a62e812f2e4d13280f2b78712b6d344cfb7 (diff) | |
| download | busybox-w32-58ca629fd27cd9d7f91a8ea90435cdb3f15381aa.tar.gz busybox-w32-58ca629fd27cd9d7f91a8ea90435cdb3f15381aa.tar.bz2 busybox-w32-58ca629fd27cd9d7f91a8ea90435cdb3f15381aa.zip | |
start-stop-daemon: do not lose error messages with -b
function old new delta
start_stop_daemon_main 1186 1206 +20
bb_daemonize_or_rexec 196 212 +16
bb_banner 47 46 -1
packed_usage 34656 34645 -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/2 up/down: 36/-12) Total: 24 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'debianutils')
| -rw-r--r-- | debianutils/start_stop_daemon.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 04ba8baa7..00fa0a82c 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
| @@ -71,7 +71,7 @@ Options which are valid for --start only: | |||
| 71 | done after the chroot if the -r|--chroot option is set. | 71 | done after the chroot if the -r|--chroot option is set. |
| 72 | When not specified, start-stop-daemon will change directory to the | 72 | When not specified, start-stop-daemon will change directory to the |
| 73 | root directory before starting the process. | 73 | root directory before starting the process. |
| 74 | ^^^^ Seems to be false, no default "/" chdir is done. | 74 | ^^^^ Gentoo does not have the default chdir("/"). Debian does. |
| 75 | Tested -S with 1.21.22: | 75 | Tested -S with 1.21.22: |
| 76 | "start-stop-daemon -S -x /bin/pwd" is the minimum needed to run pwd. | 76 | "start-stop-daemon -S -x /bin/pwd" is the minimum needed to run pwd. |
| 77 | "start-stop-daemon -S -a /bin/pwd -n pwd" works too. | 77 | "start-stop-daemon -S -a /bin/pwd -n pwd" works too. |
| @@ -111,7 +111,6 @@ Misc options: | |||
| 111 | //config: -o|--oknodo ignored since we exit with 0 anyway | 111 | //config: -o|--oknodo ignored since we exit with 0 anyway |
| 112 | //config: -v|--verbose | 112 | //config: -v|--verbose |
| 113 | //config: -N|--nicelevel N | 113 | //config: -N|--nicelevel N |
| 114 | //config: -O|--output FILE | ||
| 115 | 114 | ||
| 116 | //applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) | 115 | //applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) |
| 117 | /* not NOEXEC: uses bb_common_bufsiz1 */ | 116 | /* not NOEXEC: uses bb_common_bufsiz1 */ |
| @@ -136,6 +135,7 @@ Misc options: | |||
| 136 | //usage: "\n -x EXECUTABLE Program to run" | 135 | //usage: "\n -x EXECUTABLE Program to run" |
| 137 | //usage: "\n -a NAME Zeroth argument" | 136 | //usage: "\n -a NAME Zeroth argument" |
| 138 | //usage: "\n -b Background" | 137 | //usage: "\n -b Background" |
| 138 | //usage: "\n -O FILE Append stdout and stderr to FILE" | ||
| 139 | //usage: IF_FEATURE_START_STOP_DAEMON_FANCY( | 139 | //usage: IF_FEATURE_START_STOP_DAEMON_FANCY( |
| 140 | //usage: "\n -N N Change nice level" | 140 | //usage: "\n -N N Change nice level" |
| 141 | //usage: ) | 141 | //usage: ) |
| @@ -150,7 +150,6 @@ Misc options: | |||
| 150 | //usage: "\n -o Exit with status 0 if nothing is done" | 150 | //usage: "\n -o Exit with status 0 if nothing is done" |
| 151 | //usage: "\n -v Verbose" | 151 | //usage: "\n -v Verbose" |
| 152 | //usage: "\n -q Quiet" | 152 | //usage: "\n -q Quiet" |
| 153 | //usage: "\n -O FILE Append stdout and stderr to FILE" | ||
| 154 | //usage: ) | 153 | //usage: ) |
| 155 | 154 | ||
| 156 | /* Override ENABLE_FEATURE_PIDFILE */ | 155 | /* Override ENABLE_FEATURE_PIDFILE */ |
| @@ -178,20 +177,20 @@ enum { | |||
| 178 | OPT_d = (1 << 11), // -d | 177 | OPT_d = (1 << 11), // -d |
| 179 | OPT_x = (1 << 12), // -x | 178 | OPT_x = (1 << 12), // -x |
| 180 | OPT_p = (1 << 13), // -p | 179 | OPT_p = (1 << 13), // -p |
| 181 | OPT_OKNODO = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o | 180 | OPT_OUTPUT = (1 << 14), // -O |
| 182 | OPT_VERBOSE = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v | 181 | OPT_OKNODO = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o |
| 183 | OPT_NICELEVEL = (1 << 16) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N | 182 | OPT_VERBOSE = (1 << 16) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v |
| 184 | OPT_OUTPUT = (1 << 17) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -O | 183 | OPT_NICELEVEL = (1 << 17) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N |
| 185 | }; | 184 | }; |
| 186 | #define QUIET (option_mask32 & OPT_QUIET) | 185 | #define QUIET (option_mask32 & OPT_QUIET) |
| 187 | #define TEST (option_mask32 & OPT_TEST) | 186 | #define TEST (option_mask32 & OPT_TEST) |
| 188 | 187 | ||
| 189 | struct globals { | 188 | struct globals { |
| 190 | struct pid_list *found_procs; | 189 | struct pid_list *found_procs; |
| 191 | char *userspec; | 190 | const char *userspec; |
| 192 | char *cmdname; | 191 | const char *cmdname; |
| 193 | char *execname; | 192 | const char *execname; |
| 194 | char *pidfile; | 193 | const char *pidfile; |
| 195 | char *execname_cmpbuf; | 194 | char *execname_cmpbuf; |
| 196 | unsigned execname_sizeof; | 195 | unsigned execname_sizeof; |
| 197 | int user_id; | 196 | int user_id; |
| @@ -361,7 +360,7 @@ static void do_procinit(void) | |||
| 361 | 360 | ||
| 362 | static int do_stop(void) | 361 | static int do_stop(void) |
| 363 | { | 362 | { |
| 364 | char *what; | 363 | const char *what; |
| 365 | struct pid_list *p; | 364 | struct pid_list *p; |
| 366 | int killed = 0; | 365 | int killed = 0; |
| 367 | 366 | ||
| @@ -408,7 +407,7 @@ static int do_stop(void) | |||
| 408 | } | 407 | } |
| 409 | ret: | 408 | ret: |
| 410 | if (ENABLE_FEATURE_CLEAN_UP) | 409 | if (ENABLE_FEATURE_CLEAN_UP) |
| 411 | free(what); | 410 | free((char *)what); |
| 412 | return killed; | 411 | return killed; |
| 413 | } | 412 | } |
| 414 | 413 | ||
| @@ -449,22 +448,22 @@ int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
| 449 | int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | 448 | int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) |
| 450 | { | 449 | { |
| 451 | unsigned opt; | 450 | unsigned opt; |
| 452 | char *signame; | 451 | const char *signame; |
| 453 | char *startas = NULL; | 452 | const char *startas = NULL; |
| 454 | char *chuid; | 453 | char *chuid; |
| 455 | char *chdir; | 454 | const char *chdir; |
| 455 | const char *output = NULL; | ||
| 456 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | 456 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY |
| 457 | // char *retry_arg = NULL; | 457 | // const char *retry_arg = NULL; |
| 458 | // int retries = -1; | 458 | // int retries = -1; |
| 459 | char *opt_N; | 459 | const char *opt_N; |
| 460 | char *output; | ||
| 461 | #endif | 460 | #endif |
| 462 | 461 | ||
| 463 | INIT_G(); | 462 | INIT_G(); |
| 464 | 463 | ||
| 465 | opt = GETOPT32(argv, "^" | 464 | opt = GETOPT32(argv, "^" |
| 466 | "KSbqtma:n:s:u:c:d:x:p:" | 465 | "KSbqtma:n:s:u:c:d:x:p:O:" |
| 467 | IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:O:R:") | 466 | IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") |
| 468 | "\0" | 467 | "\0" |
| 469 | "K:S:K--S:S--K" | 468 | "K:S:K--S:S--K" |
| 470 | /* -K or -S is required; they are mutually exclusive */ | 469 | /* -K or -S is required; they are mutually exclusive */ |
| @@ -479,9 +478,8 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
| 479 | IF_FEATURE_START_STOP_DAEMON_FANCY(":q-v") /* -q turns off -v */ | 478 | IF_FEATURE_START_STOP_DAEMON_FANCY(":q-v") /* -q turns off -v */ |
| 480 | , | 479 | , |
| 481 | LONGOPTS | 480 | LONGOPTS |
| 482 | &startas, &cmdname, &signame, &userspec, &chuid, &chdir, &execname, &pidfile | 481 | &startas, &cmdname, &signame, &userspec, &chuid, &chdir, &execname, &pidfile, &output |
| 483 | IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) | 482 | IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) |
| 484 | IF_FEATURE_START_STOP_DAEMON_FANCY(,&output) | ||
| 485 | /* We accept and ignore -R <param> / --retry <param> */ | 483 | /* We accept and ignore -R <param> / --retry <param> */ |
| 486 | IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) | 484 | IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) |
| 487 | ); | 485 | ); |
| @@ -519,7 +517,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
| 519 | } | 517 | } |
| 520 | if (!startas) /* -a is not given: use -x EXECUTABLE or argv[0] */ | 518 | if (!startas) /* -a is not given: use -x EXECUTABLE or argv[0] */ |
| 521 | startas = execname; | 519 | startas = execname; |
| 522 | *--argv = startas; | 520 | *--argv = (char *)startas; |
| 523 | } | 521 | } |
| 524 | if (execname) { | 522 | if (execname) { |
| 525 | G.execname_sizeof = strlen(execname) + 1; | 523 | G.execname_sizeof = strlen(execname) + 1; |
| @@ -578,8 +576,11 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
| 578 | } | 576 | } |
| 579 | /* Child */ | 577 | /* Child */ |
| 580 | setsid(); /* detach from controlling tty */ | 578 | setsid(); /* detach from controlling tty */ |
| 581 | /* Redirect stdio to /dev/null, close extra FDs */ | 579 | /* Redirect stdin to /dev/null, close extra FDs */ |
| 582 | bb_daemon_helper(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS); | 580 | /* Testcase: "start-stop-daemon -Sb -d /does/not/exist usleep 1" should not eat error message */ |
| 581 | bb_daemon_helper(DAEMON_DEVNULL_STDIN + DAEMON_CLOSE_EXTRA_FDS); | ||
| 582 | if (!output) | ||
| 583 | output = bb_dev_null; /* redirect output just before execv */ | ||
| 583 | /* On Linux, session leader can acquire ctty | 584 | /* On Linux, session leader can acquire ctty |
| 584 | * unknowingly, by opening a tty. | 585 | * unknowingly, by opening a tty. |
| 585 | * Prevent this: stop being a session leader. | 586 | * Prevent this: stop being a session leader. |
| @@ -618,14 +619,12 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
| 618 | if (opt & OPT_d) { | 619 | if (opt & OPT_d) { |
| 619 | xchdir(chdir); | 620 | xchdir(chdir); |
| 620 | } | 621 | } |
| 621 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | 622 | if (output) { |
| 622 | if (opt & OPT_OUTPUT) { | ||
| 623 | int outfd = xopen(output, O_WRONLY | O_CREAT | O_APPEND); | 623 | int outfd = xopen(output, O_WRONLY | O_CREAT | O_APPEND); |
| 624 | xmove_fd(outfd, STDOUT_FILENO); | 624 | xmove_fd(outfd, STDOUT_FILENO); |
| 625 | xdup2(STDOUT_FILENO, STDERR_FILENO); | 625 | xdup2(STDOUT_FILENO, STDERR_FILENO); |
| 626 | /* on execv error, the message goes to -O file. This is intended */ | 626 | /* on execv error, the message goes to -O file. This is intended */ |
| 627 | } | 627 | } |
| 628 | #endif | ||
| 629 | /* Try: | 628 | /* Try: |
| 630 | * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 | 629 | * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 |
| 631 | * should exec "/bin/usleep", but argv[0] should be "qwerty": | 630 | * should exec "/bin/usleep", but argv[0] should be "qwerty": |
