diff options
| author | Louai Al-Khanji <louai@astranis.com> | 2023-11-07 21:41:32 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-11-07 21:44:07 +0100 |
| commit | 389c0458da7d6e941886ea3b846c98cfd63dfdd3 (patch) | |
| tree | 854ff2402640633ad8330e7eda2197a8907cc29e /debianutils | |
| parent | d17c0a348fc10897d86e0e96aa98be5ac88d6fdd (diff) | |
| download | busybox-w32-389c0458da7d6e941886ea3b846c98cfd63dfdd3.tar.gz busybox-w32-389c0458da7d6e941886ea3b846c98cfd63dfdd3.tar.bz2 busybox-w32-389c0458da7d6e941886ea3b846c98cfd63dfdd3.zip | |
start-stop-daemon: implement option -O|--output
If specified redirect command stdout and stderr to given pathname.
function old new delta
start_stop_daemon_main 1130 1186 +56
start_stop_daemon_longopts 164 173 +9
packed_usage 34653 34656 +3
.rodata 105384 105386 +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 70/0) Total: 70 bytes
Signed-off-by: Louai Al-Khanji <louai@astranis.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'debianutils')
| -rw-r--r-- | debianutils/start_stop_daemon.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 8573c6990..56a933fcb 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
| @@ -18,9 +18,9 @@ One (only) of these must be given: | |||
| 18 | -K,--stop Stop | 18 | -K,--stop Stop |
| 19 | -T,--status Check for the existence of a process, return exitcode (since version 1.16.1) | 19 | -T,--status Check for the existence of a process, return exitcode (since version 1.16.1) |
| 20 | 0 - program is running | 20 | 0 - program is running |
| 21 | 1 - program is not running and the pid file exists. | 21 | 1 - program is not running and the pid file exists |
| 22 | 3 - program is not running. | 22 | 3 - program is not running |
| 23 | 4 - can't determine program status. | 23 | 4 - can't determine program status |
| 24 | 24 | ||
| 25 | Search for matching processes. | 25 | Search for matching processes. |
| 26 | If --stop is given, stop all matching processes (by sending a signal). | 26 | If --stop is given, stop all matching processes (by sending a signal). |
| @@ -41,6 +41,7 @@ with /proc/$PID/exe or argv[0] (comm can't be matched, it never contains path)] | |||
| 41 | Unlike -n, we match against the full path: | 41 | Unlike -n, we match against the full path: |
| 42 | "ntpd" != "./ntpd" != "/path/to/ntpd" | 42 | "ntpd" != "./ntpd" != "/path/to/ntpd" |
| 43 | -p,--pidfile PID_FILE Look for processes with PID from this file | 43 | -p,--pidfile PID_FILE Look for processes with PID from this file |
| 44 | --pid PID Look for process with this pid (since version 1.17.6) | ||
| 44 | --ppid PPID Look for processes with parent pid (since version 1.17.7) | 45 | --ppid PPID Look for processes with parent pid (since version 1.17.7) |
| 45 | 46 | ||
| 46 | Options which are valid for --start only: | 47 | Options which are valid for --start only: |
| @@ -72,10 +73,10 @@ Options which are valid for --start only: | |||
| 72 | root directory before starting the process. | 73 | root directory before starting the process. |
| 73 | ^^^^ Seems to be false, no default "/" chdir is done. | 74 | ^^^^ Seems to be false, no default "/" chdir is done. |
| 74 | Tested -S with 1.21.22: | 75 | Tested -S with 1.21.22: |
| 75 | "start-stop-daemon -S -n pwd -a /bin/pwd" is the minimum needed to run pwd. | 76 | "start-stop-daemon -S -x /bin/pwd" is the minimum needed to run pwd. |
| 76 | "start-stop-daemon -S -n pwd -x /bin/pwd" works too. | 77 | "start-stop-daemon -S -a /bin/pwd -n pwd" works too. |
| 77 | "start-stop-daemon -S -a /bin/pwd -x /bin/pwd" works too. | 78 | "start-stop-daemon -S -a /bin/pwd" does NOT work. |
| 78 | Earlier versions were less picky (which?) | 79 | Earlier versions were less picky (which? Or is it only Gentoo's clone?) |
| 79 | 80 | ||
| 80 | Options which are valid for --stop only: | 81 | Options which are valid for --stop only: |
| 81 | -s,--signal SIG Signal to send (default:TERM) | 82 | -s,--signal SIG Signal to send (default:TERM) |
| @@ -110,6 +111,7 @@ Misc options: | |||
| 110 | //config: -o|--oknodo ignored since we exit with 0 anyway | 111 | //config: -o|--oknodo ignored since we exit with 0 anyway |
| 111 | //config: -v|--verbose | 112 | //config: -v|--verbose |
| 112 | //config: -N|--nicelevel N | 113 | //config: -N|--nicelevel N |
| 114 | //config: -O|--output FILE | ||
| 113 | 115 | ||
| 114 | //applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) | 116 | //applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) |
| 115 | /* not NOEXEC: uses bb_common_bufsiz1 */ | 117 | /* not NOEXEC: uses bb_common_bufsiz1 */ |
| @@ -147,8 +149,9 @@ Misc options: | |||
| 147 | //usage: IF_FEATURE_START_STOP_DAEMON_FANCY( | 149 | //usage: IF_FEATURE_START_STOP_DAEMON_FANCY( |
| 148 | //usage: "\n -o Exit with status 0 if nothing is done" | 150 | //usage: "\n -o Exit with status 0 if nothing is done" |
| 149 | //usage: "\n -v Verbose" | 151 | //usage: "\n -v Verbose" |
| 150 | //usage: ) | ||
| 151 | //usage: "\n -q Quiet" | 152 | //usage: "\n -q Quiet" |
| 153 | //usage: "\n -O PILE Append stdout and stderr to FILE" | ||
| 154 | //usage: ) | ||
| 152 | 155 | ||
| 153 | /* Override ENABLE_FEATURE_PIDFILE */ | 156 | /* Override ENABLE_FEATURE_PIDFILE */ |
| 154 | #define WANT_PIDFILE 1 | 157 | #define WANT_PIDFILE 1 |
| @@ -178,6 +181,7 @@ enum { | |||
| 178 | OPT_OKNODO = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o | 181 | OPT_OKNODO = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o |
| 179 | OPT_VERBOSE = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v | 182 | OPT_VERBOSE = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v |
| 180 | OPT_NICELEVEL = (1 << 16) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N | 183 | OPT_NICELEVEL = (1 << 16) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N |
| 184 | OPT_OUTPUT = (1 << 17) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -O | ||
| 181 | }; | 185 | }; |
| 182 | #define QUIET (option_mask32 & OPT_QUIET) | 186 | #define QUIET (option_mask32 & OPT_QUIET) |
| 183 | #define TEST (option_mask32 & OPT_TEST) | 187 | #define TEST (option_mask32 & OPT_TEST) |
| @@ -420,6 +424,7 @@ static const char start_stop_daemon_longopts[] ALIGN1 = | |||
| 420 | "oknodo\0" No_argument "o" | 424 | "oknodo\0" No_argument "o" |
| 421 | "verbose\0" No_argument "v" | 425 | "verbose\0" No_argument "v" |
| 422 | "nicelevel\0" Required_argument "N" | 426 | "nicelevel\0" Required_argument "N" |
| 427 | "output\0" Required_argument "O" | ||
| 423 | # endif | 428 | # endif |
| 424 | "startas\0" Required_argument "a" | 429 | "startas\0" Required_argument "a" |
| 425 | "name\0" Required_argument "n" | 430 | "name\0" Required_argument "n" |
| @@ -452,33 +457,42 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
| 452 | // char *retry_arg = NULL; | 457 | // char *retry_arg = NULL; |
| 453 | // int retries = -1; | 458 | // int retries = -1; |
| 454 | char *opt_N; | 459 | char *opt_N; |
| 460 | char *output; | ||
| 455 | #endif | 461 | #endif |
| 456 | 462 | ||
| 457 | INIT_G(); | 463 | INIT_G(); |
| 458 | 464 | ||
| 459 | opt = GETOPT32(argv, "^" | 465 | opt = GETOPT32(argv, "^" |
| 460 | "KSbqtma:n:s:u:c:d:x:p:" | 466 | "KSbqtma:n:s:u:c:d:x:p:" |
| 461 | IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") | 467 | IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:O:R:") |
| 462 | "\0" | 468 | "\0" |
| 463 | "K:S:K--S:S--K" | 469 | "K:S:K--S:S--K" |
| 464 | /* -K or -S is required; they are mutually exclusive */ | 470 | /* -K or -S is required; they are mutually exclusive */ |
| 465 | ":m?p" /* -p is required if -m is given */ | 471 | ":m?p" /* -p is required if -m is given */ |
| 466 | ":K?xpun" /* -xpun (at least one) is required if -K is given */ | 472 | ":K?xpun" /* -xpun (at least one) is required if -K is given */ |
| 467 | /* (the above does not seem to be enforced by Debian, it does nothing | 473 | /* (the above does not seem to be enforced by Gentoo, it does nothing |
| 468 | * if no matching is specified with -K, and it ignores ARGS | 474 | * if no matching is specified with -K, and it ignores ARGS |
| 469 | * - does not take ARGS[0] as program name to kill) | 475 | * - does not take ARGS[0] as program name to kill) |
| 470 | */ | 476 | */ |
| 471 | // /* -xa (at least one) is required if -S is given */ | 477 | // ":S?xa" /* -xa (at least one) is required if -S is given */ |
| 472 | //WRONG: "start-stop-daemon -S -- sleep 5" is a valid invocation | 478 | //Gentoo clone: "start-stop-daemon -S -- sleep 5" is a valid invocation |
| 473 | IF_FEATURE_START_STOP_DAEMON_FANCY(":q-v") /* -q turns off -v */ | 479 | IF_FEATURE_START_STOP_DAEMON_FANCY(":q-v") /* -q turns off -v */ |
| 474 | , | 480 | , |
| 475 | LONGOPTS | 481 | LONGOPTS |
| 476 | &startas, &cmdname, &signame, &userspec, &chuid, &chdir, &execname, &pidfile | 482 | &startas, &cmdname, &signame, &userspec, &chuid, &chdir, &execname, &pidfile |
| 477 | IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) | 483 | IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) |
| 484 | IF_FEATURE_START_STOP_DAEMON_FANCY(,&output) | ||
| 478 | /* We accept and ignore -R <param> / --retry <param> */ | 485 | /* We accept and ignore -R <param> / --retry <param> */ |
| 479 | IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) | 486 | IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) |
| 480 | ); | 487 | ); |
| 481 | 488 | ||
| 489 | //-O requires --background and absolute pathname (tested with 1.21.22). | ||
| 490 | //We don't bother requiring that (smaller code): | ||
| 491 | //#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | ||
| 492 | // if ((opt & OPT_OUTPUT) && !(opt & OPT_BACKGROUND)) | ||
| 493 | // bb_show_usage(); | ||
| 494 | //#endif | ||
| 495 | |||
| 482 | if (opt & OPT_s) { | 496 | if (opt & OPT_s) { |
| 483 | signal_nr = get_signum(signame); | 497 | signal_nr = get_signum(signame); |
| 484 | if (signal_nr < 0) bb_show_usage(); | 498 | if (signal_nr < 0) bb_show_usage(); |
| @@ -604,6 +618,14 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
| 604 | if (opt & OPT_d) { | 618 | if (opt & OPT_d) { |
| 605 | xchdir(chdir); | 619 | xchdir(chdir); |
| 606 | } | 620 | } |
| 621 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | ||
| 622 | if (opt & OPT_OUTPUT) { | ||
| 623 | int outfd = xopen(output, O_WRONLY | O_CREAT | O_APPEND); | ||
| 624 | xmove_fd(outfd, STDOUT_FILENO); | ||
| 625 | xdup2(STDOUT_FILENO, STDERR_FILENO); | ||
| 626 | /* on execv error, the message goes to -O file. This is intended */ | ||
| 627 | } | ||
| 628 | #endif | ||
| 607 | /* Try: | 629 | /* Try: |
| 608 | * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 | 630 | * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 |
| 609 | * should exec "/bin/usleep", but argv[0] should be "qwerty": | 631 | * should exec "/bin/usleep", but argv[0] should be "qwerty": |
