start-stop-daemon: add -d DIR chdir option

Add option to change the running directory before starting the process.
This can be done using -d or --chdir options. Add also test cases to
start-stop-daemon to test out the directory change option.

function                                             old     new   delta
packed_usage                                       34602   34648     +46
start_stop_daemon_main                              1107    1130     +23
start_stop_daemon_longopts                           156     164      +8
.rodata                                           105382  105384      +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 79/0)               Total: 79 bytes

Signed-off-by: ejaaskel <esa.jaaskela@suomi24.fi>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
master
ejaaskel 2023-11-07 07:12:40 +01:00 committed by Denys Vlasenko
parent 0c71497e65
commit 73f28134fc
3 changed files with 41 additions and 15 deletions

2
TODO
View File

@ -222,8 +222,6 @@ Minor stuff:
--- ---
unify progress_meter. wget, flash_eraseall, pipe_progress, fbsplash, setfiles. unify progress_meter. wget, flash_eraseall, pipe_progress, fbsplash, setfiles.
--- ---
support start-stop-daemon -d <chdir-path>
---
(TODO list after discussion 11.05.2009) (TODO list after discussion 11.05.2009)

View File

@ -11,7 +11,7 @@
/* /*
This is how it is supposed to work: This is how it is supposed to work:
start-stop-daemon [OPTIONS] [--start|--stop] [[--] ARGS...] start-stop-daemon [OPTIONS] [--start|--stop] [[--] ARGS]
One (only) of these must be given: One (only) of these must be given:
-S,--start Start -S,--start Start
@ -58,13 +58,14 @@ Options which are valid for --start only:
priority can be optionally specified by appending a : priority can be optionally specified by appending a :
followed by the value. The default priority is 0. The followed by the value. The default priority is 0. The
currently supported policy values are other, fifo and rr. currently supported policy values are other, fifo and rr.
-r,--chroot root Change directory and chroot to root before starting the -r,--chroot DIR Change directory and chroot to DIR before starting the
process. Please note that the pidfile is also written after process. Please note that the pidfile is also written after
the chroot. the chroot.
-d,--chdir path Change directory to path before starting the process. This is -d,--chdir DIR Change directory to DIR before starting the process. This is
done after the chroot if the -r|--chroot option is set. When done after the chroot if the -r|--chroot option is set.
not specified, start-stop-daemon will change directory to the When not specified, start-stop-daemon will change directory to the
root directory before starting the process. root directory before starting the process.
^^^^ Seems to be false, no default "/" chdir is done.
Options which are valid for --stop only: Options which are valid for --stop only:
-s,--signal SIG Signal to send (default:TERM) -s,--signal SIG Signal to send (default:TERM)
@ -106,7 +107,7 @@ Misc options:
//kbuild:lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o //kbuild:lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o
//usage:#define start_stop_daemon_trivial_usage //usage:#define start_stop_daemon_trivial_usage
//usage: "-S|-K [OPTIONS] [-- ARGS...]" //usage: "-S|-K [OPTIONS] [-- ARGS]"
//usage:#define start_stop_daemon_full_usage "\n\n" //usage:#define start_stop_daemon_full_usage "\n\n"
//usage: "Search for matching processes, and then\n" //usage: "Search for matching processes, and then\n"
//usage: "-S: start a process unless a matching process is found\n" //usage: "-S: start a process unless a matching process is found\n"
@ -127,6 +128,7 @@ Misc options:
//usage: "\n -N N Change nice level" //usage: "\n -N N Change nice level"
//usage: ) //usage: )
//usage: "\n -c USER[:[GRP]] Change user/group" //usage: "\n -c USER[:[GRP]] Change user/group"
//usage: "\n -d DIR Change to DIR"
//usage: "\n -m Write PID to pidfile specified by -p" //usage: "\n -m Write PID to pidfile specified by -p"
//usage: "\n-K only:" //usage: "\n-K only:"
//usage: "\n -s SIG Signal to send" //usage: "\n -s SIG Signal to send"
@ -160,11 +162,12 @@ enum {
OPT_s = (1 << 8), // -s OPT_s = (1 << 8), // -s
OPT_u = (1 << 9), // -u OPT_u = (1 << 9), // -u
OPT_c = (1 << 10), // -c OPT_c = (1 << 10), // -c
OPT_x = (1 << 11), // -x OPT_d = (1 << 11), // -d
OPT_p = (1 << 12), // -p OPT_x = (1 << 12), // -x
OPT_OKNODO = (1 << 13) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o OPT_p = (1 << 13), // -p
OPT_VERBOSE = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v OPT_OKNODO = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o
OPT_NICELEVEL = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N OPT_VERBOSE = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v
OPT_NICELEVEL = (1 << 16) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N
}; };
#define QUIET (option_mask32 & OPT_QUIET) #define QUIET (option_mask32 & OPT_QUIET)
#define TEST (option_mask32 & OPT_TEST) #define TEST (option_mask32 & OPT_TEST)
@ -413,6 +416,7 @@ static const char start_stop_daemon_longopts[] ALIGN1 =
"signal\0" Required_argument "s" "signal\0" Required_argument "s"
"user\0" Required_argument "u" "user\0" Required_argument "u"
"chuid\0" Required_argument "c" "chuid\0" Required_argument "c"
"chdir\0" Required_argument "d"
"exec\0" Required_argument "x" "exec\0" Required_argument "x"
"pidfile\0" Required_argument "p" "pidfile\0" Required_argument "p"
# if ENABLE_FEATURE_START_STOP_DAEMON_FANCY # if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
@ -433,6 +437,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
char *signame; char *signame;
char *startas = NULL; char *startas = NULL;
char *chuid; char *chuid;
char *chdir;
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
// char *retry_arg = NULL; // char *retry_arg = NULL;
// int retries = -1; // int retries = -1;
@ -442,7 +447,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
INIT_G(); INIT_G();
opt = GETOPT32(argv, "^" opt = GETOPT32(argv, "^"
"KSbqtma:n:s:u:c:x:p:" "KSbqtma:n:s:u:c:d:x:p:"
IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
"\0" "\0"
"K:S:K--S:S--K" "K:S:K--S:S--K"
@ -458,7 +463,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
IF_FEATURE_START_STOP_DAEMON_FANCY(":q-v") /* -q turns off -v */ IF_FEATURE_START_STOP_DAEMON_FANCY(":q-v") /* -q turns off -v */
, ,
LONGOPTS LONGOPTS
&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile &startas, &cmdname, &signame, &userspec, &chuid, &chdir, &execname, &pidfile
IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
/* We accept and ignore -R <param> / --retry <param> */ /* We accept and ignore -R <param> / --retry <param> */
IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL)
@ -586,6 +591,9 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
setgroups(1, &ugid.gid); setgroups(1, &ugid.gid);
} }
} }
if (opt & OPT_d) {
xchdir(chdir);
}
/* Try: /* Try:
* strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000
* should exec "/bin/usleep", but argv[0] should be "qwerty": * should exec "/bin/usleep", but argv[0] should be "qwerty":

View File

@ -11,6 +11,21 @@ testing "start-stop-daemon -x without -a" \
"0\n" \ "0\n" \
"" "" "" ""
testing "start-stop-daemon -x with -d on existing directory" \
'start-stop-daemon -S -d /tmp -x true 2>&1; echo $?' \
"0\n" \
"" ""
testing "start-stop-daemon -x with -d on existing and check dir" \
'output=$(start-stop-daemon -S -d /tmp -x pwd); echo $output' \
"/tmp\n" \
"" ""
testing "start-stop-daemon -x with --chdir on existing and check dir" \
'output=$(start-stop-daemon -S --chdir /tmp -x pwd); echo $output' \
"/tmp\n" \
"" ""
testing "start-stop-daemon -a without -x" \ testing "start-stop-daemon -a without -x" \
'start-stop-daemon -S -a false 2>&1; echo $?' \ 'start-stop-daemon -S -a false 2>&1; echo $?' \
"1\n" \ "1\n" \
@ -21,6 +36,11 @@ testing "start-stop-daemon without -x and -a" \
"1\n" \ "1\n" \
"" "" "" ""
testing "start-stop-daemon -x with -d on non-existing directory" \
'start-stop-daemon -S -d /non-existent -x true > /dev/null 2>&1; echo $?' \
"1\n" \
"" ""
# This runs /bin/false with argv[0..2] of { "qwerty", "false", NULL }. # This runs /bin/false with argv[0..2] of { "qwerty", "false", NULL }.
# #
# Unfortunately, this does not actually check argv[0] correctness, # Unfortunately, this does not actually check argv[0] correctness,